blob: 86162c21877fcde45ad00514476e6f1106fdee14 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000019#if defined(__VMS)
20# include <ctype.h> /* tolower() */
21# include <descrip.h> /* string descriptors */
22# include <dvidef.h> /* DVI$_name */
23# include <file.h> /* -> O_RDWR */
24# include <jpidef.h> /* JPI$_name */
25# include <lib$routines.h> /* LIB$name */
26# include <ots$routines.h> /* OTS$name */
27# include <ssdef.h> /* SS$_name */
28# include <unixio.h>
29# include <unixlib.h>
30# include <stat.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000031# include <wait.h> /* define wait() */
32#endif /* defined(__VMS) */
33
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000035"This module provides access to operating system functionality that is\n\
36standardized by the C Standard and the POSIX standard (a thinly\n\
37disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000038corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000040#ifndef Py_USING_UNICODE
41/* This is used in signatures of functions. */
42#define Py_UNICODE void
43#endif
44
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#if defined(PYOS_OS2)
46#define INCL_DOS
47#define INCL_DOSERRORS
48#define INCL_DOSPROCESS
49#define INCL_NOPMAPI
50#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000051#if defined(PYCC_GCC)
52#include <ctype.h>
53#include <io.h>
54#include <stdio.h>
55#include <process.h>
56#include "osdefs.h"
57#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000058#endif
59
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#include <sys/types.h>
61#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000062
Guido van Rossum36bc6801995-06-14 22:54:23 +000063#ifdef HAVE_SYS_WAIT_H
64#include <sys/wait.h> /* For WNOHANG */
65#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000066
Guido van Rossuma376cc51996-12-05 23:43:35 +000067#ifdef HAVE_SIGNAL_H
68#include <signal.h>
69#endif
70
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#ifdef HAVE_FCNTL_H
72#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000073#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Guido van Rossuma6535fd2001-10-18 19:44:10 +000075#ifdef HAVE_GRP_H
76#include <grp.h>
77#endif
78
Barry Warsaw5676bd12003-01-07 20:57:09 +000079#ifdef HAVE_SYSEXITS_H
80#include <sysexits.h>
81#endif /* HAVE_SYSEXITS_H */
82
Guido van Rossuma4916fa1996-05-23 22:58:55 +000083/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000084/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000085#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000086#include <process.h>
87#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000088#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000089#define HAVE_GETCWD 1
90#define HAVE_OPENDIR 1
91#define HAVE_SYSTEM 1
92#if defined(__OS2__)
93#define HAVE_EXECV 1
94#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000095#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000096#include <process.h>
97#else
98#ifdef __BORLANDC__ /* Borland compiler */
99#define HAVE_EXECV 1
100#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_OPENDIR 1
102#define HAVE_PIPE 1
103#define HAVE_POPEN 1
104#define HAVE_SYSTEM 1
105#define HAVE_WAIT 1
106#else
107#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000108#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000109#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000110#define HAVE_EXECV 1
111#define HAVE_PIPE 1
112#define HAVE_POPEN 1
113#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000114#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000115#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000116#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
117/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#else /* all other compilers */
119/* Unix functions that the configure script doesn't check for */
120#define HAVE_EXECV 1
121#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000122#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
123#define HAVE_FORK1 1
124#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#define HAVE_GETCWD 1
126#define HAVE_GETEGID 1
127#define HAVE_GETEUID 1
128#define HAVE_GETGID 1
129#define HAVE_GETPPID 1
130#define HAVE_GETUID 1
131#define HAVE_KILL 1
132#define HAVE_OPENDIR 1
133#define HAVE_PIPE 1
134#define HAVE_POPEN 1
135#define HAVE_SYSTEM 1
136#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000137#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000138#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#endif /* _MSC_VER */
140#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000141#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000142#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000145
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000146#if defined(sun) && !defined(__SVR4)
147/* SunOS 4.1.4 doesn't have prototypes for these: */
148extern int rename(const char *, const char *);
149extern int pclose(FILE *);
150extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000151extern int fsync(int);
152extern int lstat(const char *, struct stat *);
153extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000154#endif
155
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000156#if defined(__sgi)&&_COMPILER_VERSION>=700
157/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
158 (default) */
159extern char *ctermid_r(char *);
160#endif
161
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000162#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000163#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000164extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000165#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000166#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000171#endif
172#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int chdir(char *);
174extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int chdir(const char *);
177extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000178#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000179#ifdef __BORLANDC__
180extern int chmod(const char *, int);
181#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000182extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000183#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int chown(const char *, uid_t, gid_t);
185extern char *getcwd(char *, int);
186extern char *strerror(int);
187extern int link(const char *, const char *);
188extern int rename(const char *, const char *);
189extern int stat(const char *, struct stat *);
190extern int unlink(const char *);
191extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000193extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000194#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000199
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_UTIME_H
203#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000204#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000206#ifdef HAVE_SYS_UTIME_H
207#include <sys/utime.h>
208#define HAVE_UTIME_H /* pretend we do for the rest of this file */
209#endif /* HAVE_SYS_UTIME_H */
210
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#ifdef HAVE_SYS_TIMES_H
212#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000213#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214
215#ifdef HAVE_SYS_PARAM_H
216#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000217#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218
219#ifdef HAVE_SYS_UTSNAME_H
220#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000221#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000225#define NAMLEN(dirent) strlen((dirent)->d_name)
226#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000227#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#include <direct.h>
229#define NAMLEN(dirent) strlen((dirent)->d_name)
230#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000232#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000233#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000234#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#endif
237#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#endif
240#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#endif
243#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#include <direct.h>
247#include <io.h>
248#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000249#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000250#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000252#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000253#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000254#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossumd48f2521997-12-05 22:19:34 +0000257#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260
Tim Petersbc2e10e2002-03-03 23:17:02 +0000261#ifndef MAXPATHLEN
262#define MAXPATHLEN 1024
263#endif /* MAXPATHLEN */
264
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000265#ifdef UNION_WAIT
266/* Emulate some macros on systems that have a union instead of macros */
267
268#ifndef WIFEXITED
269#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
270#endif
271
272#ifndef WEXITSTATUS
273#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
274#endif
275
276#ifndef WTERMSIG
277#define WTERMSIG(u_wait) ((u_wait).w_termsig)
278#endif
279
280#endif /* UNION_WAIT */
281
Greg Wardb48bc172000-03-01 21:51:56 +0000282/* Don't use the "_r" form if we don't need it (also, won't have a
283 prototype for it, at least on Solaris -- maybe others as well?). */
284#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
285#define USE_CTERMID_R
286#endif
287
288#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
289#define USE_TMPNAM_R
290#endif
291
Fred Drake699f3522000-06-29 21:12:41 +0000292/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000293#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000294#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000295# define STAT _stati64
296# define FSTAT _fstati64
297# define STRUCT_STAT struct _stati64
298#else
299# define STAT stat
300# define FSTAT fstat
301# define STRUCT_STAT struct stat
302#endif
303
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000304#if defined(MAJOR_IN_MKDEV)
305#include <sys/mkdev.h>
306#else
307#if defined(MAJOR_IN_SYSMACROS)
308#include <sys/sysmacros.h>
309#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000310#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
311#include <sys/mkdev.h>
312#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000313#endif
Fred Drake699f3522000-06-29 21:12:41 +0000314
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000316#ifdef WITH_NEXT_FRAMEWORK
317/* On Darwin/MacOSX a shared library or framework has no access to
318** environ directly, we must obtain it with _NSGetEnviron().
319*/
320#include <crt_externs.h>
321static char **environ;
322#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000324#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000326#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000327/* add some values to provide a similar environment like POSIX */
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000328static
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000329void
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000330vms_add_posix_env(PyObject *d)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000331{
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000332 PyObject *o;
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000333 char* str;
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000334
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000335 str = getenv("LINES");
336 o = Py_BuildValue("s", str);
337 if (o != NULL) {
338 (void)PyDict_SetItemString(d, "LINES", o);
339 Py_DECREF(o);
340 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000341
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000342 str = getenv("COLUMNS");
343 o = Py_BuildValue("s", str);
344 if (o != NULL) {
345 (void)PyDict_SetItemString(d, "COLUMNS", o);
346 Py_DECREF(o);
347 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000348
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000349 str = getenv("USER");
350 o = Py_BuildValue("s", str);
351 if (o != NULL) {
352 (void)PyDict_SetItemString(d, "USERNAME", o);
353 Py_DECREF(o);
354 }
355 o = Py_BuildValue("s", str);
356 if (o != NULL) {
357 (void)PyDict_SetItemString(d, "LOGNAME", o);
358 Py_DECREF(o);
359 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000360
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000361 str = getenv("HOME");
362 o = Py_BuildValue("s", str);
363 if (o != NULL) {
364 (void)PyDict_SetItemString(d, "HOME", o);
365 Py_DECREF(o);
366 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000367
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000368 str = getenv("PATH");
369 o = Py_BuildValue("s", str);
370 if (o != NULL) {
371 (void)PyDict_SetItemString(d, "PATH", o);
372 Py_DECREF(o);
373 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000374 /* OS = "OpenVMS" */
375 o = PyString_FromString ("OpenVMS");
376 if (o != NULL) {
377 (void)PyDict_SetItemString(d, "OS", o);
378 Py_DECREF(o);
379 }
380}
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000381#endif /* __VMS */
382
Barry Warsaw53699e91996-12-10 23:23:01 +0000383static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000384convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385{
Barry Warsaw53699e91996-12-10 23:23:01 +0000386 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000388 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 if (d == NULL)
390 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000391#ifdef WITH_NEXT_FRAMEWORK
392 if (environ == NULL)
393 environ = *_NSGetEnviron();
394#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395 if (environ == NULL)
396 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000397 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000399 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000400 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 char *p = strchr(*e, '=');
402 if (p == NULL)
403 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000404 k = PyString_FromStringAndSize(*e, (int)(p-*e));
405 if (k == NULL) {
406 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000408 }
409 v = PyString_FromString(p+1);
410 if (v == NULL) {
411 PyErr_Clear();
412 Py_DECREF(k);
413 continue;
414 }
415 if (PyDict_GetItem(d, k) == NULL) {
416 if (PyDict_SetItem(d, k, v) != 0)
417 PyErr_Clear();
418 }
419 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000420 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000422#if defined(__VMS)
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000423 vms_add_posix_env(d);
424#elif defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000425 {
426 APIRET rc;
427 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
428
429 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000430 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000431 PyObject *v = PyString_FromString(buffer);
432 PyDict_SetItemString(d, "BEGINLIBPATH", v);
433 Py_DECREF(v);
434 }
435 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
436 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
437 PyObject *v = PyString_FromString(buffer);
438 PyDict_SetItemString(d, "ENDLIBPATH", v);
439 Py_DECREF(v);
440 }
441 }
442#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000443 return d;
444}
445
446
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447/* Set a POSIX-specific error from errno, and return NULL */
448
Barry Warsawd58d7641998-07-23 16:14:40 +0000449static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000450posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000451{
Barry Warsawca74da41999-02-09 19:31:45 +0000452 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453}
Barry Warsawd58d7641998-07-23 16:14:40 +0000454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000455posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000456{
Barry Warsawca74da41999-02-09 19:31:45 +0000457 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000458}
459
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000460#ifdef Py_WIN_WIDE_FILENAMES
461static PyObject *
462posix_error_with_unicode_filename(Py_UNICODE* name)
463{
464 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
465}
466#endif /* Py_WIN_WIDE_FILENAMES */
467
468
Mark Hammondef8b6542001-05-13 08:04:26 +0000469static PyObject *
470posix_error_with_allocated_filename(char* name)
471{
472 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
473 PyMem_Free(name);
474 return rc;
475}
476
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000477#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000478static PyObject *
479win32_error(char* function, char* filename)
480{
Mark Hammond33a6da92000-08-15 00:46:38 +0000481 /* XXX We should pass the function name along in the future.
482 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000483 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000484 Windows error object, which is non-trivial.
485 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000486 errno = GetLastError();
487 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000488 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000489 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000490 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000491}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000492
493#ifdef Py_WIN_WIDE_FILENAMES
494static PyObject *
495win32_error_unicode(char* function, Py_UNICODE* filename)
496{
497 /* XXX - see win32_error for comments on 'function' */
498 errno = GetLastError();
499 if (filename)
500 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
501 else
502 return PyErr_SetFromWindowsErr(errno);
503}
504
505static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
506{
507 /* XXX Perhaps we should make this API an alias of
508 PyObject_Unicode() instead ?! */
509 if (PyUnicode_CheckExact(obj)) {
510 Py_INCREF(obj);
511 return obj;
512 }
513 if (PyUnicode_Check(obj)) {
514 /* For a Unicode subtype that's not a Unicode object,
515 return a true Unicode object with the same data. */
516 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
517 PyUnicode_GET_SIZE(obj));
518 }
519 return PyUnicode_FromEncodedObject(obj,
520 Py_FileSystemDefaultEncoding,
521 "strict");
522}
523
524#endif /* Py_WIN_WIDE_FILENAMES */
525
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000526#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000527
Guido van Rossumd48f2521997-12-05 22:19:34 +0000528#if defined(PYOS_OS2)
529/**********************************************************************
530 * Helper Function to Trim and Format OS/2 Messages
531 **********************************************************************/
532 static void
533os2_formatmsg(char *msgbuf, int msglen, char *reason)
534{
535 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
536
537 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
538 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
539
540 while (lastc > msgbuf && isspace(*lastc))
541 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
542 }
543
544 /* Add Optional Reason Text */
545 if (reason) {
546 strcat(msgbuf, " : ");
547 strcat(msgbuf, reason);
548 }
549}
550
551/**********************************************************************
552 * Decode an OS/2 Operating System Error Code
553 *
554 * A convenience function to lookup an OS/2 error code and return a
555 * text message we can use to raise a Python exception.
556 *
557 * Notes:
558 * The messages for errors returned from the OS/2 kernel reside in
559 * the file OSO001.MSG in the \OS2 directory hierarchy.
560 *
561 **********************************************************************/
562 static char *
563os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
564{
565 APIRET rc;
566 ULONG msglen;
567
568 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
569 Py_BEGIN_ALLOW_THREADS
570 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
571 errorcode, "oso001.msg", &msglen);
572 Py_END_ALLOW_THREADS
573
574 if (rc == NO_ERROR)
575 os2_formatmsg(msgbuf, msglen, reason);
576 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000577 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000578 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000579
580 return msgbuf;
581}
582
583/* Set an OS/2-specific error and return NULL. OS/2 kernel
584 errors are not in a global variable e.g. 'errno' nor are
585 they congruent with posix error numbers. */
586
587static PyObject * os2_error(int code)
588{
589 char text[1024];
590 PyObject *v;
591
592 os2_strerror(text, sizeof(text), code, "");
593
594 v = Py_BuildValue("(is)", code, text);
595 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000596 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000597 Py_DECREF(v);
598 }
599 return NULL; /* Signal to Python that an Exception is Pending */
600}
601
602#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603
604/* POSIX generic methods */
605
Barry Warsaw53699e91996-12-10 23:23:01 +0000606static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000607posix_fildes(PyObject *fdobj, int (*func)(int))
608{
609 int fd;
610 int res;
611 fd = PyObject_AsFileDescriptor(fdobj);
612 if (fd < 0)
613 return NULL;
614 Py_BEGIN_ALLOW_THREADS
615 res = (*func)(fd);
616 Py_END_ALLOW_THREADS
617 if (res < 0)
618 return posix_error();
619 Py_INCREF(Py_None);
620 return Py_None;
621}
Guido van Rossum21142a01999-01-08 21:05:37 +0000622
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000623#ifdef Py_WIN_WIDE_FILENAMES
624static int
625unicode_file_names(void)
626{
627 static int canusewide = -1;
628 if (canusewide == -1) {
629 /* As per doc for ::GetVersion(), this is the correct test for
630 the Windows NT family. */
631 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
632 }
633 return canusewide;
634}
635#endif
636
Guido van Rossum21142a01999-01-08 21:05:37 +0000637static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000638posix_1str(PyObject *args, char *format, int (*func)(const char*),
639 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000640{
Mark Hammondef8b6542001-05-13 08:04:26 +0000641 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000642 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000643#ifdef Py_WIN_WIDE_FILENAMES
644 if (unicode_file_names()) {
645 PyUnicodeObject *po;
646 if (PyArg_ParseTuple(args, wformat, &po)) {
647 Py_BEGIN_ALLOW_THREADS
648 /* PyUnicode_AS_UNICODE OK without thread
649 lock as it is a simple dereference. */
650 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
651 Py_END_ALLOW_THREADS
652 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000653 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000654 Py_INCREF(Py_None);
655 return Py_None;
656 }
657 /* Drop the argument parsing error as narrow
658 strings are also valid. */
659 PyErr_Clear();
660 }
661#else
662 /* Platforms that don't support Unicode filenames
663 shouldn't be passing these extra params */
664 assert(wformat==NULL && wfunc == NULL);
665#endif
666
Tim Peters5aa91602002-01-30 05:46:57 +0000667 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000668 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000669 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000670 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000671 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000672 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000673 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000674 return posix_error_with_allocated_filename(path1);
675 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000676 Py_INCREF(Py_None);
677 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000678}
679
Barry Warsaw53699e91996-12-10 23:23:01 +0000680static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000681posix_2str(PyObject *args,
682 char *format,
683 int (*func)(const char *, const char *),
684 char *wformat,
685 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000686{
Mark Hammondef8b6542001-05-13 08:04:26 +0000687 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000688 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000689#ifdef Py_WIN_WIDE_FILENAMES
690 if (unicode_file_names()) {
691 PyObject *po1;
692 PyObject *po2;
693 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
694 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
695 PyObject *wpath1;
696 PyObject *wpath2;
697 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
698 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
699 if (!wpath1 || !wpath2) {
700 Py_XDECREF(wpath1);
701 Py_XDECREF(wpath2);
702 return NULL;
703 }
704 Py_BEGIN_ALLOW_THREADS
705 /* PyUnicode_AS_UNICODE OK without thread
706 lock as it is a simple dereference. */
707 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
708 PyUnicode_AS_UNICODE(wpath2));
709 Py_END_ALLOW_THREADS
710 Py_XDECREF(wpath1);
711 Py_XDECREF(wpath2);
712 if (res != 0)
713 return posix_error();
714 Py_INCREF(Py_None);
715 return Py_None;
716 }
717 /* Else flow through as neither is Unicode. */
718 }
719 /* Drop the argument parsing error as narrow
720 strings are also valid. */
721 PyErr_Clear();
722 }
723#else
724 /* Platforms that don't support Unicode filenames
725 shouldn't be passing these extra params */
726 assert(wformat==NULL && wfunc == NULL);
727#endif
728
Mark Hammondef8b6542001-05-13 08:04:26 +0000729 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000730 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000731 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000732 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000733 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000734 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000735 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000736 PyMem_Free(path1);
737 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000738 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000739 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000741 Py_INCREF(Py_None);
742 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000743}
744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000745PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000746"stat_result: Result from stat or lstat.\n\n\
747This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000748 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000749or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
750\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000751Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000752they are available as attributes only.\n\
753\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000754See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000755
756static PyStructSequence_Field stat_result_fields[] = {
757 {"st_mode", "protection bits"},
758 {"st_ino", "inode"},
759 {"st_dev", "device"},
760 {"st_nlink", "number of hard links"},
761 {"st_uid", "user ID of owner"},
762 {"st_gid", "group ID of owner"},
763 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000764 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
765 {NULL, "integer time of last access"},
766 {NULL, "integer time of last modification"},
767 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000768 {"st_atime", "time of last access"},
769 {"st_mtime", "time of last modification"},
770 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000771#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000772 {"st_blksize", "blocksize for filesystem I/O"},
773#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000774#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000775 {"st_blocks", "number of blocks allocated"},
776#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000777#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000778 {"st_rdev", "device type (if inode device)"},
779#endif
780 {0}
781};
782
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000783#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000784#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000785#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000786#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000787#endif
788
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000789#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000790#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
791#else
792#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
793#endif
794
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000795#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000796#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
797#else
798#define ST_RDEV_IDX ST_BLOCKS_IDX
799#endif
800
801static PyStructSequence_Desc stat_result_desc = {
802 "stat_result", /* name */
803 stat_result__doc__, /* doc */
804 stat_result_fields,
805 10
806};
807
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000808PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000809"statvfs_result: Result from statvfs or fstatvfs.\n\n\
810This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000811 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000812or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000813\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000814See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000815
816static PyStructSequence_Field statvfs_result_fields[] = {
817 {"f_bsize", },
818 {"f_frsize", },
819 {"f_blocks", },
820 {"f_bfree", },
821 {"f_bavail", },
822 {"f_files", },
823 {"f_ffree", },
824 {"f_favail", },
825 {"f_flag", },
826 {"f_namemax",},
827 {0}
828};
829
830static PyStructSequence_Desc statvfs_result_desc = {
831 "statvfs_result", /* name */
832 statvfs_result__doc__, /* doc */
833 statvfs_result_fields,
834 10
835};
836
837static PyTypeObject StatResultType;
838static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000839static newfunc structseq_new;
840
841static PyObject *
842statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
843{
844 PyStructSequence *result;
845 int i;
846
847 result = (PyStructSequence*)structseq_new(type, args, kwds);
848 if (!result)
849 return NULL;
850 /* If we have been initialized from a tuple,
851 st_?time might be set to None. Initialize it
852 from the int slots. */
853 for (i = 7; i <= 9; i++) {
854 if (result->ob_item[i+3] == Py_None) {
855 Py_DECREF(Py_None);
856 Py_INCREF(result->ob_item[i]);
857 result->ob_item[i+3] = result->ob_item[i];
858 }
859 }
860 return (PyObject*)result;
861}
862
863
864
865/* If true, st_?time is float. */
866static int _stat_float_times = 0;
867
868PyDoc_STRVAR(stat_float_times__doc__,
869"stat_float_times([newval]) -> oldval\n\n\
870Determine whether os.[lf]stat represents time stamps as float objects.\n\
871If newval is True, future calls to stat() return floats, if it is False,\n\
872future calls return ints. \n\
873If newval is omitted, return the current setting.\n");
874
875static PyObject*
876stat_float_times(PyObject* self, PyObject *args)
877{
878 int newval = -1;
879 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
880 return NULL;
881 if (newval == -1)
882 /* Return old value */
883 return PyBool_FromLong(_stat_float_times);
884 _stat_float_times = newval;
885 Py_INCREF(Py_None);
886 return Py_None;
887}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000888
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000889static void
890fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
891{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000892 PyObject *fval,*ival;
893#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000894 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000895#else
896 ival = PyInt_FromLong((long)sec);
897#endif
898 if (_stat_float_times) {
899 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
900 } else {
901 fval = ival;
902 Py_INCREF(fval);
903 }
904 PyStructSequence_SET_ITEM(v, index, ival);
905 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000906}
907
Tim Peters5aa91602002-01-30 05:46:57 +0000908/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000909 (used by posix_stat() and posix_fstat()) */
910static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000911_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000912{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000913 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000914 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000915 if (v == NULL)
916 return NULL;
917
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000918 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000919#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000920 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000921 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000922#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000923 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000924#endif
925#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000926 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000927 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000928#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000929 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000930#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000931 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
932 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
933 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000934#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000935 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000936 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000937#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000938 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000939#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000940
941#ifdef HAVE_STAT_TV_NSEC
942 ansec = st.st_atim.tv_nsec;
943 mnsec = st.st_mtim.tv_nsec;
944 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000945#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000946 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000947#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000948 fill_time(v, 7, st.st_atime, ansec);
949 fill_time(v, 8, st.st_mtime, mnsec);
950 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000951
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000952#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000953 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000954 PyInt_FromLong((long)st.st_blksize));
955#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000956#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000957 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000958 PyInt_FromLong((long)st.st_blocks));
959#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000960#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000961 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
962 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000963#endif
964
965 if (PyErr_Occurred()) {
966 Py_DECREF(v);
967 return NULL;
968 }
969
970 return v;
971}
972
Barry Warsaw53699e91996-12-10 23:23:01 +0000973static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000974posix_do_stat(PyObject *self, PyObject *args,
975 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000976#ifdef __VMS
977 int (*statfunc)(const char *, STRUCT_STAT *, ...),
978#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000979 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000980#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000981 char *wformat,
982 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000983{
Fred Drake699f3522000-06-29 21:12:41 +0000984 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000985 char *path = NULL; /* pass this to stat; do not free() it */
986 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000987 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000988
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000989#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000990 int pathlen;
991 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000992#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000993
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000994
995#ifdef Py_WIN_WIDE_FILENAMES
996 /* If on wide-character-capable OS see if argument
997 is Unicode and if so use wide API. */
998 if (unicode_file_names()) {
999 PyUnicodeObject *po;
1000 if (PyArg_ParseTuple(args, wformat, &po)) {
1001 Py_UNICODE wpath[MAX_PATH+1];
1002 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
1003 /* the library call can blow up if the file name is too long! */
1004 if (pathlen > MAX_PATH) {
1005 errno = ENAMETOOLONG;
1006 return posix_error();
1007 }
1008 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
1009 /* Remove trailing slash or backslash, unless it's the current
1010 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1011 */
1012 if (pathlen > 0 &&
1013 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
1014 /* It does end with a slash -- exempt the root drive cases. */
1015 /* XXX UNC root drives should also be exempted? */
1016 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
1017 /* leave it alone */;
1018 else {
1019 /* nuke the trailing backslash */
1020 wpath[pathlen-1] = L'\0';
1021 }
1022 }
1023 Py_BEGIN_ALLOW_THREADS
1024 /* PyUnicode_AS_UNICODE result OK without
1025 thread lock as it is a simple dereference. */
1026 res = wstatfunc(wpath, &st);
1027 Py_END_ALLOW_THREADS
1028 if (res != 0)
1029 return posix_error_with_unicode_filename(wpath);
1030 return _pystat_fromstructstat(st);
1031 }
1032 /* Drop the argument parsing error as narrow strings
1033 are also valid. */
1034 PyErr_Clear();
1035 }
1036#endif
1037
Tim Peters5aa91602002-01-30 05:46:57 +00001038 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001039 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001040 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001041 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001042
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001043#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +00001044 pathlen = strlen(path);
1045 /* the library call can blow up if the file name is too long! */
1046 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +00001047 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +00001048 errno = ENAMETOOLONG;
1049 return posix_error();
1050 }
1051
Tim Peters500bd032001-12-19 19:05:01 +00001052 /* Remove trailing slash or backslash, unless it's the current
1053 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1054 */
1055 if (pathlen > 0 &&
1056 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
1057 /* It does end with a slash -- exempt the root drive cases. */
1058 /* XXX UNC root drives should also be exempted? */
1059 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
1060 /* leave it alone */;
1061 else {
1062 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001063 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +00001064 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +00001065 path = pathcopy;
1066 }
1067 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001068#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001069
Barry Warsaw53699e91996-12-10 23:23:01 +00001070 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001071 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001072 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001073 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001074 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001075
Tim Peters500bd032001-12-19 19:05:01 +00001076 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001077 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001078}
1079
1080
1081/* POSIX methods */
1082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001084"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001085Use the real uid/gid to test for access to a path. Note that most\n\
1086operations will use the effective uid/gid, therefore this routine can\n\
1087be used in a suid/sgid environment to test if the invoking user has the\n\
1088specified access to the path. The mode argument can be F_OK to test\n\
1089existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001090
1091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001092posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001093{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001094 char *path;
1095 int mode;
1096 int res;
1097
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001098 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001099 return NULL;
1100 Py_BEGIN_ALLOW_THREADS
1101 res = access(path, mode);
1102 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001103 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001104}
1105
Guido van Rossumd371ff11999-01-25 16:12:23 +00001106#ifndef F_OK
1107#define F_OK 0
1108#endif
1109#ifndef R_OK
1110#define R_OK 4
1111#endif
1112#ifndef W_OK
1113#define W_OK 2
1114#endif
1115#ifndef X_OK
1116#define X_OK 1
1117#endif
1118
1119#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001120PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001121"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001122Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001123
1124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001125posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001126{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001127 int id;
1128 char *ret;
1129
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001130 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001131 return NULL;
1132
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001133#if defined(__VMS)
1134 /* DECC V5.0 - only about FD= 0 @@ try getname()+$getdvi(dvi$_devnam) */
1135 if (id == 0) {
1136 ret = ttyname();
1137 }
1138 else {
1139 ret = NULL;
1140 }
1141#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001142 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001143#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001144 if (ret == NULL)
1145 return(posix_error());
1146 return(PyString_FromString(ret));
1147}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001148#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001149
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001150#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001151PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001152"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001153Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001154
1155static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001156posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001157{
1158 char *ret;
1159 char buffer[L_ctermid];
1160
Greg Wardb48bc172000-03-01 21:51:56 +00001161#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001162 ret = ctermid_r(buffer);
1163#else
1164 ret = ctermid(buffer);
1165#endif
1166 if (ret == NULL)
1167 return(posix_error());
1168 return(PyString_FromString(buffer));
1169}
1170#endif
1171
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001172PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001173"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001174Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001175
Barry Warsaw53699e91996-12-10 23:23:01 +00001176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001177posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001179#ifdef MS_WINDOWS
1180 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1181#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1182 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001183#elif defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001184 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
1185 NULL, NULL);
1186#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001187 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001188#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189}
1190
Fred Drake4d1e64b2002-04-15 19:40:07 +00001191#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001192PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001193"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001194Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001195opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001196
1197static PyObject *
1198posix_fchdir(PyObject *self, PyObject *fdobj)
1199{
1200 return posix_fildes(fdobj, fchdir);
1201}
1202#endif /* HAVE_FCHDIR */
1203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001205PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001206"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001207Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001208
Barry Warsaw53699e91996-12-10 23:23:01 +00001209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001210posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211{
Mark Hammondef8b6542001-05-13 08:04:26 +00001212 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001213 int i;
1214 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001215 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001216 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001217 return NULL;
1218 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001219 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001220 Py_END_ALLOW_THREADS
1221 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001222 return posix_error_with_allocated_filename(path);
1223 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001224 Py_INCREF(Py_None);
1225 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226}
1227
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001228
Martin v. Löwis244edc82001-10-04 22:44:26 +00001229#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001230PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001231"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001232Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001233
1234static PyObject *
1235posix_chroot(PyObject *self, PyObject *args)
1236{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001237 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001238}
1239#endif
1240
Guido van Rossum21142a01999-01-08 21:05:37 +00001241#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001242PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001243"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001244force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001245
1246static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001247posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001248{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001249 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001250}
1251#endif /* HAVE_FSYNC */
1252
1253#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001254
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001255#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001256extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1257#endif
1258
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001259PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001260"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001261force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001262 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001263
1264static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001265posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001266{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001267 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001268}
1269#endif /* HAVE_FDATASYNC */
1270
1271
Fredrik Lundh10723342000-07-10 16:38:09 +00001272#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001273PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001274"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001275Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001276
Barry Warsaw53699e91996-12-10 23:23:01 +00001277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001278posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001279{
Mark Hammondef8b6542001-05-13 08:04:26 +00001280 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001281 int uid, gid;
1282 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001283 if (!PyArg_ParseTuple(args, "etii:chown",
1284 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001285 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001286 return NULL;
1287 Py_BEGIN_ALLOW_THREADS
1288 res = chown(path, (uid_t) uid, (gid_t) gid);
1289 Py_END_ALLOW_THREADS
1290 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001291 return posix_error_with_allocated_filename(path);
1292 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001293 Py_INCREF(Py_None);
1294 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001295}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001296#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001297
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001298#ifdef HAVE_LCHOWN
1299PyDoc_STRVAR(posix_lchown__doc__,
1300"lchown(path, uid, gid)\n\n\
1301Change the owner and group id of path to the numeric uid and gid.\n\
1302This function will not follow symbolic links.");
1303
1304static PyObject *
1305posix_lchown(PyObject *self, PyObject *args)
1306{
1307 char *path = NULL;
1308 int uid, gid;
1309 int res;
1310 if (!PyArg_ParseTuple(args, "etii:lchown",
1311 Py_FileSystemDefaultEncoding, &path,
1312 &uid, &gid))
1313 return NULL;
1314 Py_BEGIN_ALLOW_THREADS
1315 res = lchown(path, (uid_t) uid, (gid_t) gid);
1316 Py_END_ALLOW_THREADS
Neal Norwitze241ce82003-02-17 18:17:05 +00001317 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001318 return posix_error_with_allocated_filename(path);
1319 PyMem_Free(path);
1320 Py_INCREF(Py_None);
1321 return Py_None;
1322}
1323#endif /* HAVE_LCHOWN */
1324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001325
Guido van Rossum36bc6801995-06-14 22:54:23 +00001326#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001327PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001328"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001329Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001330
Barry Warsaw53699e91996-12-10 23:23:01 +00001331static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001332posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333{
1334 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001335 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001336
Barry Warsaw53699e91996-12-10 23:23:01 +00001337 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001338#if defined(PYOS_OS2) && defined(PYCC_GCC)
1339 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001340#elif defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001341 /* 0 = force Unix-style path if in the VMS DCL environment! */
1342 res = getcwd(buf, sizeof buf, 0);
1343#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001344 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001345#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001346 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001347 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001349 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001351
Walter Dörwald3b918c32002-11-21 20:18:46 +00001352#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001353PyDoc_STRVAR(posix_getcwdu__doc__,
1354"getcwdu() -> path\n\n\
1355Return a unicode string representing the current working directory.");
1356
1357static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001358posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001359{
1360 char buf[1026];
1361 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001362
1363#ifdef Py_WIN_WIDE_FILENAMES
1364 if (unicode_file_names()) {
1365 wchar_t *wres;
1366 wchar_t wbuf[1026];
1367 Py_BEGIN_ALLOW_THREADS
1368 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1369 Py_END_ALLOW_THREADS
1370 if (wres == NULL)
1371 return posix_error();
1372 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1373 }
1374#endif
1375
1376 Py_BEGIN_ALLOW_THREADS
1377#if defined(PYOS_OS2) && defined(PYCC_GCC)
1378 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001379#elif defined(__VMS)
1380 /* 0 = force Unix-style path if in the VMS DCL environment! */
1381 res = getcwd(buf, sizeof buf, 0);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001382#else
1383 res = getcwd(buf, sizeof buf);
1384#endif
1385 Py_END_ALLOW_THREADS
1386 if (res == NULL)
1387 return posix_error();
1388 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1389}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001390#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001391#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001393
Guido van Rossumb6775db1994-08-01 11:34:53 +00001394#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001395PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001396"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001397Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001398
Barry Warsaw53699e91996-12-10 23:23:01 +00001399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001400posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001401{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001402 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001403}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001404#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001405
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001406
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001407PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001408"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001409Return a list containing the names of the entries in the directory.\n\
1410\n\
1411 path: path of directory to list\n\
1412\n\
1413The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001414entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001415
Barry Warsaw53699e91996-12-10 23:23:01 +00001416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001417posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001418{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001419 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001420 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001421#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001422
Barry Warsaw53699e91996-12-10 23:23:01 +00001423 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001424 HANDLE hFindFile;
1425 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001426 /* MAX_PATH characters could mean a bigger encoded string */
1427 char namebuf[MAX_PATH*2+5];
1428 char *bufptr = namebuf;
1429 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001430
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001431#ifdef Py_WIN_WIDE_FILENAMES
1432 /* If on wide-character-capable OS see if argument
1433 is Unicode and if so use wide API. */
1434 if (unicode_file_names()) {
1435 PyUnicodeObject *po;
1436 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1437 WIN32_FIND_DATAW wFileData;
1438 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1439 Py_UNICODE wch;
1440 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1441 wnamebuf[MAX_PATH] = L'\0';
1442 len = wcslen(wnamebuf);
1443 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1444 if (wch != L'/' && wch != L'\\' && wch != L':')
1445 wnamebuf[len++] = L'/';
1446 wcscpy(wnamebuf + len, L"*.*");
1447 if ((d = PyList_New(0)) == NULL)
1448 return NULL;
1449 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1450 if (hFindFile == INVALID_HANDLE_VALUE) {
1451 errno = GetLastError();
1452 if (errno == ERROR_FILE_NOT_FOUND) {
1453 return d;
1454 }
1455 Py_DECREF(d);
1456 return win32_error_unicode("FindFirstFileW", wnamebuf);
1457 }
1458 do {
1459 if (wFileData.cFileName[0] == L'.' &&
1460 (wFileData.cFileName[1] == L'\0' ||
1461 wFileData.cFileName[1] == L'.' &&
1462 wFileData.cFileName[2] == L'\0'))
1463 continue;
1464 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1465 if (v == NULL) {
1466 Py_DECREF(d);
1467 d = NULL;
1468 break;
1469 }
1470 if (PyList_Append(d, v) != 0) {
1471 Py_DECREF(v);
1472 Py_DECREF(d);
1473 d = NULL;
1474 break;
1475 }
1476 Py_DECREF(v);
1477 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1478
1479 if (FindClose(hFindFile) == FALSE) {
1480 Py_DECREF(d);
1481 return win32_error_unicode("FindClose", wnamebuf);
1482 }
1483 return d;
1484 }
1485 /* Drop the argument parsing error as narrow strings
1486 are also valid. */
1487 PyErr_Clear();
1488 }
1489#endif
1490
Tim Peters5aa91602002-01-30 05:46:57 +00001491 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001492 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001493 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001494 if (len > 0) {
1495 char ch = namebuf[len-1];
1496 if (ch != SEP && ch != ALTSEP && ch != ':')
1497 namebuf[len++] = '/';
1498 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001499 strcpy(namebuf + len, "*.*");
1500
Barry Warsaw53699e91996-12-10 23:23:01 +00001501 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001502 return NULL;
1503
1504 hFindFile = FindFirstFile(namebuf, &FileData);
1505 if (hFindFile == INVALID_HANDLE_VALUE) {
1506 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001507 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001508 return d;
1509 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001510 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001511 }
1512 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001513 if (FileData.cFileName[0] == '.' &&
1514 (FileData.cFileName[1] == '\0' ||
1515 FileData.cFileName[1] == '.' &&
1516 FileData.cFileName[2] == '\0'))
1517 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001518 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001519 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001520 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001521 d = NULL;
1522 break;
1523 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001524 if (PyList_Append(d, v) != 0) {
1525 Py_DECREF(v);
1526 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001527 d = NULL;
1528 break;
1529 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001530 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001531 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1532
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001533 if (FindClose(hFindFile) == FALSE) {
1534 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001535 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001536 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001537
1538 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001539
Tim Peters0bb44a42000-09-15 07:44:49 +00001540#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001541
1542#ifndef MAX_PATH
1543#define MAX_PATH CCHMAXPATH
1544#endif
1545 char *name, *pt;
1546 int len;
1547 PyObject *d, *v;
1548 char namebuf[MAX_PATH+5];
1549 HDIR hdir = 1;
1550 ULONG srchcnt = 1;
1551 FILEFINDBUF3 ep;
1552 APIRET rc;
1553
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001554 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001555 return NULL;
1556 if (len >= MAX_PATH) {
1557 PyErr_SetString(PyExc_ValueError, "path too long");
1558 return NULL;
1559 }
1560 strcpy(namebuf, name);
1561 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001562 if (*pt == ALTSEP)
1563 *pt = SEP;
1564 if (namebuf[len-1] != SEP)
1565 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001566 strcpy(namebuf + len, "*.*");
1567
1568 if ((d = PyList_New(0)) == NULL)
1569 return NULL;
1570
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001571 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1572 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001573 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001574 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1575 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1576 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001577
1578 if (rc != NO_ERROR) {
1579 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001580 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001581 }
1582
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001583 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001584 do {
1585 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001586 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001587 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001588
1589 strcpy(namebuf, ep.achName);
1590
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001591 /* Leave Case of Name Alone -- In Native Form */
1592 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001593
1594 v = PyString_FromString(namebuf);
1595 if (v == NULL) {
1596 Py_DECREF(d);
1597 d = NULL;
1598 break;
1599 }
1600 if (PyList_Append(d, v) != 0) {
1601 Py_DECREF(v);
1602 Py_DECREF(d);
1603 d = NULL;
1604 break;
1605 }
1606 Py_DECREF(v);
1607 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1608 }
1609
1610 return d;
1611#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001612
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001613 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001615 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001616 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001617 int arg_is_unicode = 1;
1618
1619 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1620 arg_is_unicode = 0;
1621 PyErr_Clear();
1622 }
1623 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001624 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001625 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001626 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001627 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001628 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001629 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001630 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001631 return NULL;
1632 }
1633 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001634 if (ep->d_name[0] == '.' &&
1635 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001636 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001637 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001638 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001639 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001640 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641 d = NULL;
1642 break;
1643 }
Just van Rossum46c97842003-02-25 21:42:15 +00001644#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001645 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001646 PyObject *w;
1647
1648 w = PyUnicode_FromEncodedObject(v,
1649 Py_FileSystemDefaultEncoding,
1650 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001651 if (w != NULL) {
1652 Py_DECREF(v);
1653 v = w;
1654 }
1655 else {
1656 /* fall back to the original byte string, as
1657 discussed in patch #683592 */
1658 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001659 }
Just van Rossum46c97842003-02-25 21:42:15 +00001660 }
1661#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001662 if (PyList_Append(d, v) != 0) {
1663 Py_DECREF(v);
1664 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001665 d = NULL;
1666 break;
1667 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001668 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669 }
1670 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001671 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001672
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001673 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001674
Tim Peters0bb44a42000-09-15 07:44:49 +00001675#endif /* which OS */
1676} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001677
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001678#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001679/* A helper function for abspath on win32 */
1680static PyObject *
1681posix__getfullpathname(PyObject *self, PyObject *args)
1682{
1683 /* assume encoded strings wont more than double no of chars */
1684 char inbuf[MAX_PATH*2];
1685 char *inbufp = inbuf;
1686 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1687 char outbuf[MAX_PATH*2];
1688 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001689#ifdef Py_WIN_WIDE_FILENAMES
1690 if (unicode_file_names()) {
1691 PyUnicodeObject *po;
1692 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1693 Py_UNICODE woutbuf[MAX_PATH*2];
1694 Py_UNICODE *wtemp;
1695 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1696 sizeof(woutbuf)/sizeof(woutbuf[0]),
1697 woutbuf, &wtemp))
1698 return win32_error("GetFullPathName", "");
1699 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1700 }
1701 /* Drop the argument parsing error as narrow strings
1702 are also valid. */
1703 PyErr_Clear();
1704 }
1705#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001706 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1707 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001708 &insize))
1709 return NULL;
1710 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1711 outbuf, &temp))
1712 return win32_error("GetFullPathName", inbuf);
1713 return PyString_FromString(outbuf);
1714} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001715#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001717PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001718"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001719Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001720
Barry Warsaw53699e91996-12-10 23:23:01 +00001721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001722posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001723{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001724 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001725 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001726 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001727
1728#ifdef Py_WIN_WIDE_FILENAMES
1729 if (unicode_file_names()) {
1730 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001731 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001732 Py_BEGIN_ALLOW_THREADS
1733 /* PyUnicode_AS_UNICODE OK without thread lock as
1734 it is a simple dereference. */
1735 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1736 Py_END_ALLOW_THREADS
1737 if (res < 0)
1738 return posix_error();
1739 Py_INCREF(Py_None);
1740 return Py_None;
1741 }
1742 /* Drop the argument parsing error as narrow strings
1743 are also valid. */
1744 PyErr_Clear();
1745 }
1746#endif
1747
Tim Peters5aa91602002-01-30 05:46:57 +00001748 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001749 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001750 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001751 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001752#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001753 res = mkdir(path);
1754#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001755 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001756#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001757 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001758 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001759 return posix_error_with_allocated_filename(path);
1760 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001761 Py_INCREF(Py_None);
1762 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001763}
1764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001765
Guido van Rossumb6775db1994-08-01 11:34:53 +00001766#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001767#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1768#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1769#include <sys/resource.h>
1770#endif
1771#endif
1772
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001774"nice(inc) -> new_priority\n\n\
1775Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001776
Barry Warsaw53699e91996-12-10 23:23:01 +00001777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001778posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001779{
1780 int increment, value;
1781
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001782 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001783 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001784
1785 /* There are two flavours of 'nice': one that returns the new
1786 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001787 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1788 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001789
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001790 If we are of the nice family that returns the new priority, we
1791 need to clear errno before the call, and check if errno is filled
1792 before calling posix_error() on a returnvalue of -1, because the
1793 -1 may be the actual new priority! */
1794
1795 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001796 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001797#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001798 if (value == 0)
1799 value = getpriority(PRIO_PROCESS, 0);
1800#endif
1801 if (value == -1 && errno != 0)
1802 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001803 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001804 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001805}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001806#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001808
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001809PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001810"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001811Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001812
Barry Warsaw53699e91996-12-10 23:23:01 +00001813static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001814posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001815{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001816#ifdef MS_WINDOWS
1817 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1818#else
1819 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1820#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001821}
1822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001823
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001824PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001825"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001826Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001827
Barry Warsaw53699e91996-12-10 23:23:01 +00001828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001829posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001830{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001831#ifdef MS_WINDOWS
1832 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1833#else
1834 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1835#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001836}
1837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001840"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001841Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001842
Barry Warsaw53699e91996-12-10 23:23:01 +00001843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001844posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001845{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001846#ifdef MS_WINDOWS
1847 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1848#else
1849 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1850#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001851}
1852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001853
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001854#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001855PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001856"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001858
Barry Warsaw53699e91996-12-10 23:23:01 +00001859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001860posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001861{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001862 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001863 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001864 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001865 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001866 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001867 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001868 Py_END_ALLOW_THREADS
1869 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001870}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001871#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001873
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001874PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001875"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001876Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001877
Barry Warsaw53699e91996-12-10 23:23:01 +00001878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001879posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001880{
1881 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001882 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001883 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001884 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001885 if (i < 0)
1886 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001887 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001888}
1889
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001890
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001891PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001892"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001893Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001894
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001895PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001896"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001897Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001898
Barry Warsaw53699e91996-12-10 23:23:01 +00001899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001900posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001901{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001902#ifdef MS_WINDOWS
1903 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1904#else
1905 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1906#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001907}
1908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001909
Guido van Rossumb6775db1994-08-01 11:34:53 +00001910#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001911PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001912"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001913Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001914
Barry Warsaw53699e91996-12-10 23:23:01 +00001915static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001916posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001917{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001918 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001919 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001920
Barry Warsaw53699e91996-12-10 23:23:01 +00001921 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001922 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001923 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001924 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001925 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001926 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001927 u.sysname,
1928 u.nodename,
1929 u.release,
1930 u.version,
1931 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001932}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001933#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001934
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001935static int
1936extract_time(PyObject *t, long* sec, long* usec)
1937{
1938 long intval;
1939 if (PyFloat_Check(t)) {
1940 double tval = PyFloat_AsDouble(t);
1941 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1942 if (!intobj)
1943 return -1;
1944 intval = PyInt_AsLong(intobj);
1945 Py_DECREF(intobj);
1946 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001947 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001948 if (*usec < 0)
1949 /* If rounding gave us a negative number,
1950 truncate. */
1951 *usec = 0;
1952 return 0;
1953 }
1954 intval = PyInt_AsLong(t);
1955 if (intval == -1 && PyErr_Occurred())
1956 return -1;
1957 *sec = intval;
1958 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001959 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001960}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001961
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001962PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001963"utime(path, (atime, utime))\n\
1964utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001965Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001966second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001967
Barry Warsaw53699e91996-12-10 23:23:01 +00001968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001969posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001970{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001971 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001972 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001973 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001974 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001975
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001976#if defined(HAVE_UTIMES)
1977 struct timeval buf[2];
1978#define ATIME buf[0].tv_sec
1979#define MTIME buf[1].tv_sec
1980#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001981/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001982 struct utimbuf buf;
1983#define ATIME buf.actime
1984#define MTIME buf.modtime
1985#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001986#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001987 time_t buf[2];
1988#define ATIME buf[0]
1989#define MTIME buf[1]
1990#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001991#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001992
Barry Warsaw3cef8562000-05-01 16:17:24 +00001993 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001994 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001995 if (arg == Py_None) {
1996 /* optional time values not given */
1997 Py_BEGIN_ALLOW_THREADS
1998 res = utime(path, NULL);
1999 Py_END_ALLOW_THREADS
2000 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002001 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002002 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002003 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00002004 return NULL;
2005 }
2006 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002007 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2008 &atime, &ausec) == -1)
2009 return NULL;
2010 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2011 &mtime, &musec) == -1)
2012 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002013 ATIME = atime;
2014 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002015#ifdef HAVE_UTIMES
2016 buf[0].tv_usec = ausec;
2017 buf[1].tv_usec = musec;
2018 Py_BEGIN_ALLOW_THREADS
2019 res = utimes(path, buf);
2020 Py_END_ALLOW_THREADS
2021#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002022 Py_BEGIN_ALLOW_THREADS
2023 res = utime(path, UTIME_ARG);
2024 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002025#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00002026 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002027 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002028 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002029 Py_INCREF(Py_None);
2030 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002031#undef UTIME_ARG
2032#undef ATIME
2033#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002034}
2035
Guido van Rossum85e3b011991-06-03 12:42:10 +00002036
Guido van Rossum3b066191991-06-04 19:40:25 +00002037/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002038
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002039PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002040"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002042
Barry Warsaw53699e91996-12-10 23:23:01 +00002043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002044posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002045{
2046 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002047 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002048 return NULL;
2049 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002050 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002051}
2052
Martin v. Löwis114619e2002-10-07 06:44:21 +00002053#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2054static void
2055free_string_array(char **array, int count)
2056{
2057 int i;
2058 for (i = 0; i < count; i++)
2059 PyMem_Free(array[i]);
2060 PyMem_DEL(array);
2061}
2062#endif
2063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002064
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002065#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002066PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002067"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068Execute an executable path with arguments, replacing current process.\n\
2069\n\
2070 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002072
Barry Warsaw53699e91996-12-10 23:23:01 +00002073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002074posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002075{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002076 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002077 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002078 char **argvlist;
2079 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002080 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002081
Guido van Rossum89b33251993-10-22 14:26:06 +00002082 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002083 argv is a list or tuple of strings. */
2084
Martin v. Löwis114619e2002-10-07 06:44:21 +00002085 if (!PyArg_ParseTuple(args, "etO:execv",
2086 Py_FileSystemDefaultEncoding,
2087 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002088 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002089 if (PyList_Check(argv)) {
2090 argc = PyList_Size(argv);
2091 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002092 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002093 else if (PyTuple_Check(argv)) {
2094 argc = PyTuple_Size(argv);
2095 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002096 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002097 else {
Fred Drake661ea262000-10-24 19:57:45 +00002098 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002099 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002100 return NULL;
2101 }
2102
2103 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002104 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002105 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002106 return NULL;
2107 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002108
Barry Warsaw53699e91996-12-10 23:23:01 +00002109 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002110 if (argvlist == NULL) {
2111 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002112 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002113 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002114 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002115 if (!PyArg_Parse((*getitem)(argv, i), "et",
2116 Py_FileSystemDefaultEncoding,
2117 &argvlist[i])) {
2118 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002119 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002120 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002121 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002122 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002123
Guido van Rossum85e3b011991-06-03 12:42:10 +00002124 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002125 }
2126 argvlist[argc] = NULL;
2127
Guido van Rossumb6775db1994-08-01 11:34:53 +00002128#ifdef BAD_EXEC_PROTOTYPES
2129 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002130#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002131 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002132#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002133
Guido van Rossum85e3b011991-06-03 12:42:10 +00002134 /* If we get here it's definitely an error */
2135
Martin v. Löwis114619e2002-10-07 06:44:21 +00002136 free_string_array(argvlist, argc);
2137 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002138 return posix_error();
2139}
2140
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002141
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002143"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002144Execute a path with arguments and environment, replacing current process.\n\
2145\n\
2146 path: path of executable file\n\
2147 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002148 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002149
Barry Warsaw53699e91996-12-10 23:23:01 +00002150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002151posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002152{
2153 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002154 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002155 char **argvlist;
2156 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002157 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002158 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002159 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002160 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002161
2162 /* execve has three arguments: (path, argv, env), where
2163 argv is a list or tuple of strings and env is a dictionary
2164 like posix.environ. */
2165
Martin v. Löwis114619e2002-10-07 06:44:21 +00002166 if (!PyArg_ParseTuple(args, "etOO:execve",
2167 Py_FileSystemDefaultEncoding,
2168 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002169 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002170 if (PyList_Check(argv)) {
2171 argc = PyList_Size(argv);
2172 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002173 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002174 else if (PyTuple_Check(argv)) {
2175 argc = PyTuple_Size(argv);
2176 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002177 }
2178 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002179 PyErr_SetString(PyExc_TypeError,
2180 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002181 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002182 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002183 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002184 PyErr_SetString(PyExc_TypeError,
2185 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002186 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002187 }
2188
Guido van Rossum50422b42000-04-26 20:34:28 +00002189 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002190 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002191 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002192 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002193 }
2194
Barry Warsaw53699e91996-12-10 23:23:01 +00002195 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002196 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002197 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002198 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002199 }
2200 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002201 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002202 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002203 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002204 &argvlist[i]))
2205 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002206 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002207 goto fail_1;
2208 }
2209 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002210 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002211 argvlist[argc] = NULL;
2212
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002213 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002214 if (i < 0)
2215 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002216 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002217 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002218 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002219 goto fail_1;
2220 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002221 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002222 keys = PyMapping_Keys(env);
2223 vals = PyMapping_Values(env);
2224 if (!keys || !vals)
2225 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002226 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2227 PyErr_SetString(PyExc_TypeError,
2228 "execve(): env.keys() or env.values() is not a list");
2229 goto fail_2;
2230 }
Tim Peters5aa91602002-01-30 05:46:57 +00002231
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002232 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002233 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002234 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002235
2236 key = PyList_GetItem(keys, pos);
2237 val = PyList_GetItem(vals, pos);
2238 if (!key || !val)
2239 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002240
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002241 if (!PyArg_Parse(
2242 key,
2243 "s;execve() arg 3 contains a non-string key",
2244 &k) ||
2245 !PyArg_Parse(
2246 val,
2247 "s;execve() arg 3 contains a non-string value",
2248 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002249 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002250 goto fail_2;
2251 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002252
2253#if defined(PYOS_OS2)
2254 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2255 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2256#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002257 len = PyString_Size(key) + PyString_Size(val) + 2;
2258 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002259 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002260 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002261 goto fail_2;
2262 }
Tim Petersc8996f52001-12-03 20:41:00 +00002263 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002264 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002265#if defined(PYOS_OS2)
2266 }
2267#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002268 }
2269 envlist[envc] = 0;
2270
Guido van Rossumb6775db1994-08-01 11:34:53 +00002271
2272#ifdef BAD_EXEC_PROTOTYPES
2273 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002274#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002275 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002276#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002277
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002278 /* If we get here it's definitely an error */
2279
2280 (void) posix_error();
2281
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002282 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002283 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002284 PyMem_DEL(envlist[envc]);
2285 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002286 fail_1:
2287 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002288 Py_XDECREF(vals);
2289 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002290 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002291 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002292 return NULL;
2293}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002294#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002296
Guido van Rossuma1065681999-01-25 23:20:23 +00002297#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002298PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002299"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002300Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002301\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002302 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002303 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002304 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002305
2306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002307posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002308{
2309 char *path;
2310 PyObject *argv;
2311 char **argvlist;
2312 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002313 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002314 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002315
2316 /* spawnv has three arguments: (mode, path, argv), where
2317 argv is a list or tuple of strings. */
2318
Martin v. Löwis114619e2002-10-07 06:44:21 +00002319 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2320 Py_FileSystemDefaultEncoding,
2321 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002322 return NULL;
2323 if (PyList_Check(argv)) {
2324 argc = PyList_Size(argv);
2325 getitem = PyList_GetItem;
2326 }
2327 else if (PyTuple_Check(argv)) {
2328 argc = PyTuple_Size(argv);
2329 getitem = PyTuple_GetItem;
2330 }
2331 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002332 PyErr_SetString(PyExc_TypeError,
2333 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002334 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002335 return NULL;
2336 }
2337
2338 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002339 if (argvlist == NULL) {
2340 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002341 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002342 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002343 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002344 if (!PyArg_Parse((*getitem)(argv, i), "et",
2345 Py_FileSystemDefaultEncoding,
2346 &argvlist[i])) {
2347 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002348 PyErr_SetString(
2349 PyExc_TypeError,
2350 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002351 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002352 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002353 }
2354 }
2355 argvlist[argc] = NULL;
2356
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002357#if defined(PYOS_OS2) && defined(PYCC_GCC)
2358 Py_BEGIN_ALLOW_THREADS
2359 spawnval = spawnv(mode, path, argvlist);
2360 Py_END_ALLOW_THREADS
2361#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002362 if (mode == _OLD_P_OVERLAY)
2363 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002364
Tim Peters25059d32001-12-07 20:35:43 +00002365 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002366 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002367 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002368#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002369
Martin v. Löwis114619e2002-10-07 06:44:21 +00002370 free_string_array(argvlist, argc);
2371 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002372
Fred Drake699f3522000-06-29 21:12:41 +00002373 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002374 return posix_error();
2375 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002376#if SIZEOF_LONG == SIZEOF_VOID_P
2377 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002378#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002379 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002380#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002381}
2382
2383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002385"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002386Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002387\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002388 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002389 path: path of executable file\n\
2390 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002391 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002392
2393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002394posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002395{
2396 char *path;
2397 PyObject *argv, *env;
2398 char **argvlist;
2399 char **envlist;
2400 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2401 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002402 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002403 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002404 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002405
2406 /* spawnve has four arguments: (mode, path, argv, env), where
2407 argv is a list or tuple of strings and env is a dictionary
2408 like posix.environ. */
2409
Martin v. Löwis114619e2002-10-07 06:44:21 +00002410 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2411 Py_FileSystemDefaultEncoding,
2412 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002413 return NULL;
2414 if (PyList_Check(argv)) {
2415 argc = PyList_Size(argv);
2416 getitem = PyList_GetItem;
2417 }
2418 else if (PyTuple_Check(argv)) {
2419 argc = PyTuple_Size(argv);
2420 getitem = PyTuple_GetItem;
2421 }
2422 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002423 PyErr_SetString(PyExc_TypeError,
2424 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002425 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002426 }
2427 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002428 PyErr_SetString(PyExc_TypeError,
2429 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002430 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002431 }
2432
2433 argvlist = PyMem_NEW(char *, argc+1);
2434 if (argvlist == NULL) {
2435 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002436 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002437 }
2438 for (i = 0; i < argc; i++) {
2439 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002440 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002441 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002442 &argvlist[i]))
2443 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002444 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002445 goto fail_1;
2446 }
2447 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002448 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002449 argvlist[argc] = NULL;
2450
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002451 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002452 if (i < 0)
2453 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002454 envlist = PyMem_NEW(char *, i + 1);
2455 if (envlist == NULL) {
2456 PyErr_NoMemory();
2457 goto fail_1;
2458 }
2459 envc = 0;
2460 keys = PyMapping_Keys(env);
2461 vals = PyMapping_Values(env);
2462 if (!keys || !vals)
2463 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002464 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2465 PyErr_SetString(PyExc_TypeError,
2466 "spawnve(): env.keys() or env.values() is not a list");
2467 goto fail_2;
2468 }
Tim Peters5aa91602002-01-30 05:46:57 +00002469
Guido van Rossuma1065681999-01-25 23:20:23 +00002470 for (pos = 0; pos < i; pos++) {
2471 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002472 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002473
2474 key = PyList_GetItem(keys, pos);
2475 val = PyList_GetItem(vals, pos);
2476 if (!key || !val)
2477 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002478
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002479 if (!PyArg_Parse(
2480 key,
2481 "s;spawnve() arg 3 contains a non-string key",
2482 &k) ||
2483 !PyArg_Parse(
2484 val,
2485 "s;spawnve() arg 3 contains a non-string value",
2486 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002487 {
2488 goto fail_2;
2489 }
Tim Petersc8996f52001-12-03 20:41:00 +00002490 len = PyString_Size(key) + PyString_Size(val) + 2;
2491 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002492 if (p == NULL) {
2493 PyErr_NoMemory();
2494 goto fail_2;
2495 }
Tim Petersc8996f52001-12-03 20:41:00 +00002496 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002497 envlist[envc++] = p;
2498 }
2499 envlist[envc] = 0;
2500
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002501#if defined(PYOS_OS2) && defined(PYCC_GCC)
2502 Py_BEGIN_ALLOW_THREADS
2503 spawnval = spawnve(mode, path, argvlist, envlist);
2504 Py_END_ALLOW_THREADS
2505#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002506 if (mode == _OLD_P_OVERLAY)
2507 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002508
2509 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002510 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002511 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002512#endif
Tim Peters25059d32001-12-07 20:35:43 +00002513
Fred Drake699f3522000-06-29 21:12:41 +00002514 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002515 (void) posix_error();
2516 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002517#if SIZEOF_LONG == SIZEOF_VOID_P
2518 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002519#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002520 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002521#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002522
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002523 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002524 while (--envc >= 0)
2525 PyMem_DEL(envlist[envc]);
2526 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002527 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002528 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002529 Py_XDECREF(vals);
2530 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002531 fail_0:
2532 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002533 return res;
2534}
2535#endif /* HAVE_SPAWNV */
2536
2537
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002538#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002539PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002540"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002541Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2542\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002543Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002544
2545static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002546posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002547{
Neal Norwitze241ce82003-02-17 18:17:05 +00002548 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002549 if (pid == -1)
2550 return posix_error();
2551 PyOS_AfterFork();
2552 return PyInt_FromLong((long)pid);
2553}
2554#endif
2555
2556
Guido van Rossumad0ee831995-03-01 10:34:45 +00002557#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002558PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002559"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002560Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002561Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002562
Barry Warsaw53699e91996-12-10 23:23:01 +00002563static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002564posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002565{
Neal Norwitze241ce82003-02-17 18:17:05 +00002566 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002567 if (pid == -1)
2568 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002569 if (pid == 0)
2570 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002571 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002572}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002573#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002574
Neal Norwitzb59798b2003-03-21 01:43:31 +00002575/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002576/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2577#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002578#define DEV_PTY_FILE "/dev/ptc"
2579#define HAVE_DEV_PTMX
2580#else
2581#define DEV_PTY_FILE "/dev/ptmx"
2582#endif
2583
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002584#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002585#ifdef HAVE_PTY_H
2586#include <pty.h>
2587#else
2588#ifdef HAVE_LIBUTIL_H
2589#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002590#endif /* HAVE_LIBUTIL_H */
2591#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002592#ifdef HAVE_STROPTS_H
2593#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002594#endif
2595#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002596
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002597#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002598PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002599"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002600Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002601
2602static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002603posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002604{
2605 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002606#ifndef HAVE_OPENPTY
2607 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002608#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002609#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002610 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002611#ifdef sun
2612 extern char *ptsname();
2613#endif
2614#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002615
Thomas Wouters70c21a12000-07-14 14:28:33 +00002616#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002617 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2618 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002619#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002620 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2621 if (slave_name == NULL)
2622 return posix_error();
2623
2624 slave_fd = open(slave_name, O_RDWR);
2625 if (slave_fd < 0)
2626 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002627#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002628 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002629 if (master_fd < 0)
2630 return posix_error();
2631 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002632 /* change permission of slave */
2633 if (grantpt(master_fd) < 0) {
2634 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002635 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002636 }
2637 /* unlock slave */
2638 if (unlockpt(master_fd) < 0) {
2639 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002640 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002641 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002642 signal(SIGCHLD, sig_saved);
2643 slave_name = ptsname(master_fd); /* get name of slave */
2644 if (slave_name == NULL)
2645 return posix_error();
2646 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2647 if (slave_fd < 0)
2648 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002649#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002650 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2651 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002652#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002653 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002654#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002655#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002656#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002657
Fred Drake8cef4cf2000-06-28 16:40:38 +00002658 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002659
Fred Drake8cef4cf2000-06-28 16:40:38 +00002660}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002661#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002662
2663#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002664PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002665"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002666Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2667Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002668To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002669
2670static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002671posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002672{
2673 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002674
Fred Drake8cef4cf2000-06-28 16:40:38 +00002675 pid = forkpty(&master_fd, NULL, NULL, NULL);
2676 if (pid == -1)
2677 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002678 if (pid == 0)
2679 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002680 return Py_BuildValue("(ii)", pid, master_fd);
2681}
2682#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002683
Guido van Rossumad0ee831995-03-01 10:34:45 +00002684#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002685PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002686"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002687Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002688
Barry Warsaw53699e91996-12-10 23:23:01 +00002689static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002690posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002691{
Barry Warsaw53699e91996-12-10 23:23:01 +00002692 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002693}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002694#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002696
Guido van Rossumad0ee831995-03-01 10:34:45 +00002697#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002698PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002699"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002700Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002701
Barry Warsaw53699e91996-12-10 23:23:01 +00002702static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002703posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002704{
Barry Warsaw53699e91996-12-10 23:23:01 +00002705 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002706}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002707#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002708
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002709
Guido van Rossumad0ee831995-03-01 10:34:45 +00002710#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002711PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002712"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002713Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002714
Barry Warsaw53699e91996-12-10 23:23:01 +00002715static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002716posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002717{
Barry Warsaw53699e91996-12-10 23:23:01 +00002718 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002719}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002720#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002721
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002722
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002723PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002724"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002725Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002726
Barry Warsaw53699e91996-12-10 23:23:01 +00002727static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002728posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002729{
Barry Warsaw53699e91996-12-10 23:23:01 +00002730 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002731}
2732
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002733
Fred Drakec9680921999-12-13 16:37:25 +00002734#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002735PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002736"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002737Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002738
2739static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002740posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002741{
2742 PyObject *result = NULL;
2743
Fred Drakec9680921999-12-13 16:37:25 +00002744#ifdef NGROUPS_MAX
2745#define MAX_GROUPS NGROUPS_MAX
2746#else
2747 /* defined to be 16 on Solaris7, so this should be a small number */
2748#define MAX_GROUPS 64
2749#endif
2750 gid_t grouplist[MAX_GROUPS];
2751 int n;
2752
2753 n = getgroups(MAX_GROUPS, grouplist);
2754 if (n < 0)
2755 posix_error();
2756 else {
2757 result = PyList_New(n);
2758 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002759 int i;
2760 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002761 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002762 if (o == NULL) {
2763 Py_DECREF(result);
2764 result = NULL;
2765 break;
2766 }
2767 PyList_SET_ITEM(result, i, o);
2768 }
2769 }
2770 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002771
Fred Drakec9680921999-12-13 16:37:25 +00002772 return result;
2773}
2774#endif
2775
Martin v. Löwis606edc12002-06-13 21:09:11 +00002776#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002777PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002778"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002779Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002780
2781static PyObject *
2782posix_getpgid(PyObject *self, PyObject *args)
2783{
2784 int pid, pgid;
2785 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2786 return NULL;
2787 pgid = getpgid(pid);
2788 if (pgid < 0)
2789 return posix_error();
2790 return PyInt_FromLong((long)pgid);
2791}
2792#endif /* HAVE_GETPGID */
2793
2794
Guido van Rossumb6775db1994-08-01 11:34:53 +00002795#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002796PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002797"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002798Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002799
Barry Warsaw53699e91996-12-10 23:23:01 +00002800static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002801posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002802{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002803#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002804 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002805#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002806 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002807#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002808}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002809#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002810
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002811
Guido van Rossumb6775db1994-08-01 11:34:53 +00002812#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002813PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002814"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002815Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002816
Barry Warsaw53699e91996-12-10 23:23:01 +00002817static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002818posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002819{
Guido van Rossum64933891994-10-20 21:56:42 +00002820#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002821 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002822#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002823 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002824#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002825 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002826 Py_INCREF(Py_None);
2827 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002828}
2829
Guido van Rossumb6775db1994-08-01 11:34:53 +00002830#endif /* HAVE_SETPGRP */
2831
Guido van Rossumad0ee831995-03-01 10:34:45 +00002832#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002833PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002834"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002835Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002836
Barry Warsaw53699e91996-12-10 23:23:01 +00002837static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002838posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002839{
Barry Warsaw53699e91996-12-10 23:23:01 +00002840 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002841}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002842#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002843
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002844
Fred Drake12c6e2d1999-12-14 21:25:03 +00002845#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002846PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002847"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002849
2850static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002851posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002852{
Neal Norwitze241ce82003-02-17 18:17:05 +00002853 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00002854 char *name;
2855 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002856
Fred Drakea30680b2000-12-06 21:24:28 +00002857 errno = 0;
2858 name = getlogin();
2859 if (name == NULL) {
2860 if (errno)
2861 posix_error();
2862 else
2863 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002864 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002865 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002866 else
2867 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002868 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00002869
Fred Drake12c6e2d1999-12-14 21:25:03 +00002870 return result;
2871}
2872#endif
2873
Guido van Rossumad0ee831995-03-01 10:34:45 +00002874#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002876"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002878
Barry Warsaw53699e91996-12-10 23:23:01 +00002879static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002880posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002881{
Barry Warsaw53699e91996-12-10 23:23:01 +00002882 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002883}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002884#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002886
Guido van Rossumad0ee831995-03-01 10:34:45 +00002887#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002888PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002889"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002890Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002891
Barry Warsaw53699e91996-12-10 23:23:01 +00002892static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002893posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002894{
2895 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002896 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002897 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002898#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002899 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2900 APIRET rc;
2901 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002902 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002903
2904 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2905 APIRET rc;
2906 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002907 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002908
2909 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002910 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002911#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002912 if (kill(pid, sig) == -1)
2913 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002914#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002915 Py_INCREF(Py_None);
2916 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002917}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002918#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002919
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002920#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002921PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002922"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002923Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002924
2925static PyObject *
2926posix_killpg(PyObject *self, PyObject *args)
2927{
2928 int pgid, sig;
2929 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2930 return NULL;
2931 if (killpg(pgid, sig) == -1)
2932 return posix_error();
2933 Py_INCREF(Py_None);
2934 return Py_None;
2935}
2936#endif
2937
Guido van Rossumc0125471996-06-28 18:55:32 +00002938#ifdef HAVE_PLOCK
2939
2940#ifdef HAVE_SYS_LOCK_H
2941#include <sys/lock.h>
2942#endif
2943
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002944PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002945"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002946Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002947
Barry Warsaw53699e91996-12-10 23:23:01 +00002948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002949posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002950{
2951 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002952 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002953 return NULL;
2954 if (plock(op) == -1)
2955 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002956 Py_INCREF(Py_None);
2957 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002958}
2959#endif
2960
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002961
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002962#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002963PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002964"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002965Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002966
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002967#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002968#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002969static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002970async_system(const char *command)
2971{
2972 char *p, errormsg[256], args[1024];
2973 RESULTCODES rcodes;
2974 APIRET rc;
2975 char *shell = getenv("COMSPEC");
2976 if (!shell)
2977 shell = "cmd";
2978
2979 strcpy(args, shell);
2980 p = &args[ strlen(args)+1 ];
2981 strcpy(p, "/c ");
2982 strcat(p, command);
2983 p += strlen(p) + 1;
2984 *p = '\0';
2985
2986 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002987 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002988 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002989 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002990 &rcodes, shell);
2991 return rc;
2992}
2993
Guido van Rossumd48f2521997-12-05 22:19:34 +00002994static FILE *
2995popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002996{
2997 HFILE rhan, whan;
2998 FILE *retfd = NULL;
2999 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3000
Guido van Rossumd48f2521997-12-05 22:19:34 +00003001 if (rc != NO_ERROR) {
3002 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003003 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003004 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003005
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003006 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3007 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003008
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003009 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3010 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003011
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003012 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3013 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003014
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003015 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003016 }
3017
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003018 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3019 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003020
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003021 if (rc == NO_ERROR)
3022 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3023
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003024 close(oldfd); /* And Close Saved STDOUT Handle */
3025 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003026
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003027 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3028 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003029
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003030 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3031 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003032
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003033 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3034 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003035
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003036 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003037 }
3038
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003039 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3040 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003041
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003042 if (rc == NO_ERROR)
3043 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3044
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003045 close(oldfd); /* And Close Saved STDIN Handle */
3046 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003047
Guido van Rossumd48f2521997-12-05 22:19:34 +00003048 } else {
3049 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003050 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003051 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003052}
3053
3054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003055posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003056{
3057 char *name;
3058 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003059 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003060 FILE *fp;
3061 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003062 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003063 return NULL;
3064 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003065 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003066 Py_END_ALLOW_THREADS
3067 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003068 return os2_error(err);
3069
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003070 f = PyFile_FromFile(fp, name, mode, fclose);
3071 if (f != NULL)
3072 PyFile_SetBufSize(f, bufsize);
3073 return f;
3074}
3075
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003076#elif defined(PYCC_GCC)
3077
3078/* standard posix version of popen() support */
3079static PyObject *
3080posix_popen(PyObject *self, PyObject *args)
3081{
3082 char *name;
3083 char *mode = "r";
3084 int bufsize = -1;
3085 FILE *fp;
3086 PyObject *f;
3087 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3088 return NULL;
3089 Py_BEGIN_ALLOW_THREADS
3090 fp = popen(name, mode);
3091 Py_END_ALLOW_THREADS
3092 if (fp == NULL)
3093 return posix_error();
3094 f = PyFile_FromFile(fp, name, mode, pclose);
3095 if (f != NULL)
3096 PyFile_SetBufSize(f, bufsize);
3097 return f;
3098}
3099
3100/* fork() under OS/2 has lots'o'warts
3101 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3102 * most of this code is a ripoff of the win32 code, but using the
3103 * capabilities of EMX's C library routines
3104 */
3105
3106/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3107#define POPEN_1 1
3108#define POPEN_2 2
3109#define POPEN_3 3
3110#define POPEN_4 4
3111
3112static PyObject *_PyPopen(char *, int, int, int);
3113static int _PyPclose(FILE *file);
3114
3115/*
3116 * Internal dictionary mapping popen* file pointers to process handles,
3117 * for use when retrieving the process exit code. See _PyPclose() below
3118 * for more information on this dictionary's use.
3119 */
3120static PyObject *_PyPopenProcs = NULL;
3121
3122/* os2emx version of popen2()
3123 *
3124 * The result of this function is a pipe (file) connected to the
3125 * process's stdin, and a pipe connected to the process's stdout.
3126 */
3127
3128static PyObject *
3129os2emx_popen2(PyObject *self, PyObject *args)
3130{
3131 PyObject *f;
3132 int tm=0;
3133
3134 char *cmdstring;
3135 char *mode = "t";
3136 int bufsize = -1;
3137 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3138 return NULL;
3139
3140 if (*mode == 't')
3141 tm = O_TEXT;
3142 else if (*mode != 'b') {
3143 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3144 return NULL;
3145 } else
3146 tm = O_BINARY;
3147
3148 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3149
3150 return f;
3151}
3152
3153/*
3154 * Variation on os2emx.popen2
3155 *
3156 * The result of this function is 3 pipes - the process's stdin,
3157 * stdout and stderr
3158 */
3159
3160static PyObject *
3161os2emx_popen3(PyObject *self, PyObject *args)
3162{
3163 PyObject *f;
3164 int tm = 0;
3165
3166 char *cmdstring;
3167 char *mode = "t";
3168 int bufsize = -1;
3169 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3170 return NULL;
3171
3172 if (*mode == 't')
3173 tm = O_TEXT;
3174 else if (*mode != 'b') {
3175 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3176 return NULL;
3177 } else
3178 tm = O_BINARY;
3179
3180 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3181
3182 return f;
3183}
3184
3185/*
3186 * Variation on os2emx.popen2
3187 *
3188 * The result of this function is 2 pipes - the processes stdin,
3189 * and stdout+stderr combined as a single pipe.
3190 */
3191
3192static PyObject *
3193os2emx_popen4(PyObject *self, PyObject *args)
3194{
3195 PyObject *f;
3196 int tm = 0;
3197
3198 char *cmdstring;
3199 char *mode = "t";
3200 int bufsize = -1;
3201 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3202 return NULL;
3203
3204 if (*mode == 't')
3205 tm = O_TEXT;
3206 else if (*mode != 'b') {
3207 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3208 return NULL;
3209 } else
3210 tm = O_BINARY;
3211
3212 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3213
3214 return f;
3215}
3216
3217/* a couple of structures for convenient handling of multiple
3218 * file handles and pipes
3219 */
3220struct file_ref
3221{
3222 int handle;
3223 int flags;
3224};
3225
3226struct pipe_ref
3227{
3228 int rd;
3229 int wr;
3230};
3231
3232/* The following code is derived from the win32 code */
3233
3234static PyObject *
3235_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3236{
3237 struct file_ref stdio[3];
3238 struct pipe_ref p_fd[3];
3239 FILE *p_s[3];
3240 int file_count, i, pipe_err, pipe_pid;
3241 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3242 PyObject *f, *p_f[3];
3243
3244 /* file modes for subsequent fdopen's on pipe handles */
3245 if (mode == O_TEXT)
3246 {
3247 rd_mode = "rt";
3248 wr_mode = "wt";
3249 }
3250 else
3251 {
3252 rd_mode = "rb";
3253 wr_mode = "wb";
3254 }
3255
3256 /* prepare shell references */
3257 if ((shell = getenv("EMXSHELL")) == NULL)
3258 if ((shell = getenv("COMSPEC")) == NULL)
3259 {
3260 errno = ENOENT;
3261 return posix_error();
3262 }
3263
3264 sh_name = _getname(shell);
3265 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3266 opt = "/c";
3267 else
3268 opt = "-c";
3269
3270 /* save current stdio fds + their flags, and set not inheritable */
3271 i = pipe_err = 0;
3272 while (pipe_err >= 0 && i < 3)
3273 {
3274 pipe_err = stdio[i].handle = dup(i);
3275 stdio[i].flags = fcntl(i, F_GETFD, 0);
3276 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3277 i++;
3278 }
3279 if (pipe_err < 0)
3280 {
3281 /* didn't get them all saved - clean up and bail out */
3282 int saved_err = errno;
3283 while (i-- > 0)
3284 {
3285 close(stdio[i].handle);
3286 }
3287 errno = saved_err;
3288 return posix_error();
3289 }
3290
3291 /* create pipe ends */
3292 file_count = 2;
3293 if (n == POPEN_3)
3294 file_count = 3;
3295 i = pipe_err = 0;
3296 while ((pipe_err == 0) && (i < file_count))
3297 pipe_err = pipe((int *)&p_fd[i++]);
3298 if (pipe_err < 0)
3299 {
3300 /* didn't get them all made - clean up and bail out */
3301 while (i-- > 0)
3302 {
3303 close(p_fd[i].wr);
3304 close(p_fd[i].rd);
3305 }
3306 errno = EPIPE;
3307 return posix_error();
3308 }
3309
3310 /* change the actual standard IO streams over temporarily,
3311 * making the retained pipe ends non-inheritable
3312 */
3313 pipe_err = 0;
3314
3315 /* - stdin */
3316 if (dup2(p_fd[0].rd, 0) == 0)
3317 {
3318 close(p_fd[0].rd);
3319 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3320 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3321 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3322 {
3323 close(p_fd[0].wr);
3324 pipe_err = -1;
3325 }
3326 }
3327 else
3328 {
3329 pipe_err = -1;
3330 }
3331
3332 /* - stdout */
3333 if (pipe_err == 0)
3334 {
3335 if (dup2(p_fd[1].wr, 1) == 1)
3336 {
3337 close(p_fd[1].wr);
3338 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3339 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3340 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3341 {
3342 close(p_fd[1].rd);
3343 pipe_err = -1;
3344 }
3345 }
3346 else
3347 {
3348 pipe_err = -1;
3349 }
3350 }
3351
3352 /* - stderr, as required */
3353 if (pipe_err == 0)
3354 switch (n)
3355 {
3356 case POPEN_3:
3357 {
3358 if (dup2(p_fd[2].wr, 2) == 2)
3359 {
3360 close(p_fd[2].wr);
3361 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3362 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3363 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3364 {
3365 close(p_fd[2].rd);
3366 pipe_err = -1;
3367 }
3368 }
3369 else
3370 {
3371 pipe_err = -1;
3372 }
3373 break;
3374 }
3375
3376 case POPEN_4:
3377 {
3378 if (dup2(1, 2) != 2)
3379 {
3380 pipe_err = -1;
3381 }
3382 break;
3383 }
3384 }
3385
3386 /* spawn the child process */
3387 if (pipe_err == 0)
3388 {
3389 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3390 if (pipe_pid == -1)
3391 {
3392 pipe_err = -1;
3393 }
3394 else
3395 {
3396 /* save the PID into the FILE structure
3397 * NOTE: this implementation doesn't actually
3398 * take advantage of this, but do it for
3399 * completeness - AIM Apr01
3400 */
3401 for (i = 0; i < file_count; i++)
3402 p_s[i]->_pid = pipe_pid;
3403 }
3404 }
3405
3406 /* reset standard IO to normal */
3407 for (i = 0; i < 3; i++)
3408 {
3409 dup2(stdio[i].handle, i);
3410 fcntl(i, F_SETFD, stdio[i].flags);
3411 close(stdio[i].handle);
3412 }
3413
3414 /* if any remnant problems, clean up and bail out */
3415 if (pipe_err < 0)
3416 {
3417 for (i = 0; i < 3; i++)
3418 {
3419 close(p_fd[i].rd);
3420 close(p_fd[i].wr);
3421 }
3422 errno = EPIPE;
3423 return posix_error_with_filename(cmdstring);
3424 }
3425
3426 /* build tuple of file objects to return */
3427 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3428 PyFile_SetBufSize(p_f[0], bufsize);
3429 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3430 PyFile_SetBufSize(p_f[1], bufsize);
3431 if (n == POPEN_3)
3432 {
3433 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3434 PyFile_SetBufSize(p_f[0], bufsize);
3435 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3436 }
3437 else
3438 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3439
3440 /*
3441 * Insert the files we've created into the process dictionary
3442 * all referencing the list with the process handle and the
3443 * initial number of files (see description below in _PyPclose).
3444 * Since if _PyPclose later tried to wait on a process when all
3445 * handles weren't closed, it could create a deadlock with the
3446 * child, we spend some energy here to try to ensure that we
3447 * either insert all file handles into the dictionary or none
3448 * at all. It's a little clumsy with the various popen modes
3449 * and variable number of files involved.
3450 */
3451 if (!_PyPopenProcs)
3452 {
3453 _PyPopenProcs = PyDict_New();
3454 }
3455
3456 if (_PyPopenProcs)
3457 {
3458 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3459 int ins_rc[3];
3460
3461 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3462 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3463
3464 procObj = PyList_New(2);
3465 pidObj = PyInt_FromLong((long) pipe_pid);
3466 intObj = PyInt_FromLong((long) file_count);
3467
3468 if (procObj && pidObj && intObj)
3469 {
3470 PyList_SetItem(procObj, 0, pidObj);
3471 PyList_SetItem(procObj, 1, intObj);
3472
3473 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3474 if (fileObj[0])
3475 {
3476 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3477 fileObj[0],
3478 procObj);
3479 }
3480 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3481 if (fileObj[1])
3482 {
3483 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3484 fileObj[1],
3485 procObj);
3486 }
3487 if (file_count >= 3)
3488 {
3489 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3490 if (fileObj[2])
3491 {
3492 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3493 fileObj[2],
3494 procObj);
3495 }
3496 }
3497
3498 if (ins_rc[0] < 0 || !fileObj[0] ||
3499 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3500 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3501 {
3502 /* Something failed - remove any dictionary
3503 * entries that did make it.
3504 */
3505 if (!ins_rc[0] && fileObj[0])
3506 {
3507 PyDict_DelItem(_PyPopenProcs,
3508 fileObj[0]);
3509 }
3510 if (!ins_rc[1] && fileObj[1])
3511 {
3512 PyDict_DelItem(_PyPopenProcs,
3513 fileObj[1]);
3514 }
3515 if (!ins_rc[2] && fileObj[2])
3516 {
3517 PyDict_DelItem(_PyPopenProcs,
3518 fileObj[2]);
3519 }
3520 }
3521 }
3522
3523 /*
3524 * Clean up our localized references for the dictionary keys
3525 * and value since PyDict_SetItem will Py_INCREF any copies
3526 * that got placed in the dictionary.
3527 */
3528 Py_XDECREF(procObj);
3529 Py_XDECREF(fileObj[0]);
3530 Py_XDECREF(fileObj[1]);
3531 Py_XDECREF(fileObj[2]);
3532 }
3533
3534 /* Child is launched. */
3535 return f;
3536}
3537
3538/*
3539 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3540 * exit code for the child process and return as a result of the close.
3541 *
3542 * This function uses the _PyPopenProcs dictionary in order to map the
3543 * input file pointer to information about the process that was
3544 * originally created by the popen* call that created the file pointer.
3545 * The dictionary uses the file pointer as a key (with one entry
3546 * inserted for each file returned by the original popen* call) and a
3547 * single list object as the value for all files from a single call.
3548 * The list object contains the Win32 process handle at [0], and a file
3549 * count at [1], which is initialized to the total number of file
3550 * handles using that list.
3551 *
3552 * This function closes whichever handle it is passed, and decrements
3553 * the file count in the dictionary for the process handle pointed to
3554 * by this file. On the last close (when the file count reaches zero),
3555 * this function will wait for the child process and then return its
3556 * exit code as the result of the close() operation. This permits the
3557 * files to be closed in any order - it is always the close() of the
3558 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003559 *
3560 * NOTE: This function is currently called with the GIL released.
3561 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003562 */
3563
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003564static int _PyPclose(FILE *file)
3565{
3566 int result;
3567 int exit_code;
3568 int pipe_pid;
3569 PyObject *procObj, *pidObj, *intObj, *fileObj;
3570 int file_count;
3571#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003572 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003573#endif
3574
3575 /* Close the file handle first, to ensure it can't block the
3576 * child from exiting if it's the last handle.
3577 */
3578 result = fclose(file);
3579
3580#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003581 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003582#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003583 if (_PyPopenProcs)
3584 {
3585 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3586 (procObj = PyDict_GetItem(_PyPopenProcs,
3587 fileObj)) != NULL &&
3588 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3589 (intObj = PyList_GetItem(procObj,1)) != NULL)
3590 {
3591 pipe_pid = (int) PyInt_AsLong(pidObj);
3592 file_count = (int) PyInt_AsLong(intObj);
3593
3594 if (file_count > 1)
3595 {
3596 /* Still other files referencing process */
3597 file_count--;
3598 PyList_SetItem(procObj,1,
3599 PyInt_FromLong((long) file_count));
3600 }
3601 else
3602 {
3603 /* Last file for this process */
3604 if (result != EOF &&
3605 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3606 {
3607 /* extract exit status */
3608 if (WIFEXITED(exit_code))
3609 {
3610 result = WEXITSTATUS(exit_code);
3611 }
3612 else
3613 {
3614 errno = EPIPE;
3615 result = -1;
3616 }
3617 }
3618 else
3619 {
3620 /* Indicate failure - this will cause the file object
3621 * to raise an I/O error and translate the last
3622 * error code from errno. We do have a problem with
3623 * last errors that overlap the normal errno table,
3624 * but that's a consistent problem with the file object.
3625 */
3626 result = -1;
3627 }
3628 }
3629
3630 /* Remove this file pointer from dictionary */
3631 PyDict_DelItem(_PyPopenProcs, fileObj);
3632
3633 if (PyDict_Size(_PyPopenProcs) == 0)
3634 {
3635 Py_DECREF(_PyPopenProcs);
3636 _PyPopenProcs = NULL;
3637 }
3638
3639 } /* if object retrieval ok */
3640
3641 Py_XDECREF(fileObj);
3642 } /* if _PyPopenProcs */
3643
3644#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003645 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003646#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003647 return result;
3648}
3649
3650#endif /* PYCC_??? */
3651
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003652#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003653
3654/*
3655 * Portable 'popen' replacement for Win32.
3656 *
3657 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3658 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003659 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003660 */
3661
3662#include <malloc.h>
3663#include <io.h>
3664#include <fcntl.h>
3665
3666/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3667#define POPEN_1 1
3668#define POPEN_2 2
3669#define POPEN_3 3
3670#define POPEN_4 4
3671
3672static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003673static int _PyPclose(FILE *file);
3674
3675/*
3676 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003677 * for use when retrieving the process exit code. See _PyPclose() below
3678 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003679 */
3680static PyObject *_PyPopenProcs = NULL;
3681
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003682
3683/* popen that works from a GUI.
3684 *
3685 * The result of this function is a pipe (file) connected to the
3686 * processes stdin or stdout, depending on the requested mode.
3687 */
3688
3689static PyObject *
3690posix_popen(PyObject *self, PyObject *args)
3691{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003692 PyObject *f, *s;
3693 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003694
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003695 char *cmdstring;
3696 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003697 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003698 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003699 return NULL;
3700
3701 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003702
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003703 if (*mode == 'r')
3704 tm = _O_RDONLY;
3705 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003706 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003707 return NULL;
3708 } else
3709 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003710
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003711 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003712 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003713 return NULL;
3714 }
3715
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003716 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003717 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003718 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003719 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003720 else
3721 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3722
3723 return f;
3724}
3725
3726/* Variation on win32pipe.popen
3727 *
3728 * The result of this function is a pipe (file) connected to the
3729 * process's stdin, and a pipe connected to the process's stdout.
3730 */
3731
3732static PyObject *
3733win32_popen2(PyObject *self, PyObject *args)
3734{
3735 PyObject *f;
3736 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003737
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003738 char *cmdstring;
3739 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003740 int bufsize = -1;
3741 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003742 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003743
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003744 if (*mode == 't')
3745 tm = _O_TEXT;
3746 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003747 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003748 return NULL;
3749 } else
3750 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003751
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003752 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003753 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003754 return NULL;
3755 }
3756
3757 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003758
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003759 return f;
3760}
3761
3762/*
3763 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003764 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003765 * The result of this function is 3 pipes - the process's stdin,
3766 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003767 */
3768
3769static PyObject *
3770win32_popen3(PyObject *self, PyObject *args)
3771{
3772 PyObject *f;
3773 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003774
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003775 char *cmdstring;
3776 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003777 int bufsize = -1;
3778 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003779 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003780
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003781 if (*mode == 't')
3782 tm = _O_TEXT;
3783 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003784 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003785 return NULL;
3786 } else
3787 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003788
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003789 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003790 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003791 return NULL;
3792 }
3793
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003794 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003795
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003796 return f;
3797}
3798
3799/*
3800 * Variation on win32pipe.popen
3801 *
Tim Peters5aa91602002-01-30 05:46:57 +00003802 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003803 * and stdout+stderr combined as a single pipe.
3804 */
3805
3806static PyObject *
3807win32_popen4(PyObject *self, PyObject *args)
3808{
3809 PyObject *f;
3810 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003811
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003812 char *cmdstring;
3813 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003814 int bufsize = -1;
3815 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003816 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003817
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003818 if (*mode == 't')
3819 tm = _O_TEXT;
3820 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003821 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003822 return NULL;
3823 } else
3824 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003825
3826 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003827 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003828 return NULL;
3829 }
3830
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003831 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003832
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003833 return f;
3834}
3835
Mark Hammond08501372001-01-31 07:30:29 +00003836static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003837_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003838 HANDLE hStdin,
3839 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003840 HANDLE hStderr,
3841 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003842{
3843 PROCESS_INFORMATION piProcInfo;
3844 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003845 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003846 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003847 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003848 int i;
3849 int x;
3850
3851 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003852 char *comshell;
3853
Tim Peters92e4dd82002-10-05 01:47:34 +00003854 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003855 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3856 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003857
3858 /* Explicitly check if we are using COMMAND.COM. If we are
3859 * then use the w9xpopen hack.
3860 */
3861 comshell = s1 + x;
3862 while (comshell >= s1 && *comshell != '\\')
3863 --comshell;
3864 ++comshell;
3865
3866 if (GetVersion() < 0x80000000 &&
3867 _stricmp(comshell, "command.com") != 0) {
3868 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003869 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003870 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003871 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003872 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003873 }
3874 else {
3875 /*
Tim Peters402d5982001-08-27 06:37:48 +00003876 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3877 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003878 */
Mark Hammond08501372001-01-31 07:30:29 +00003879 char modulepath[_MAX_PATH];
3880 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003881 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3882 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003883 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003884 x = i+1;
3885 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003886 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003887 strncat(modulepath,
3888 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003889 (sizeof(modulepath)/sizeof(modulepath[0]))
3890 -strlen(modulepath));
3891 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003892 /* Eeek - file-not-found - possibly an embedding
3893 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003894 */
Tim Peters5aa91602002-01-30 05:46:57 +00003895 strncpy(modulepath,
3896 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003897 sizeof(modulepath)/sizeof(modulepath[0]));
3898 if (modulepath[strlen(modulepath)-1] != '\\')
3899 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003900 strncat(modulepath,
3901 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003902 (sizeof(modulepath)/sizeof(modulepath[0]))
3903 -strlen(modulepath));
3904 /* No where else to look - raise an easily identifiable
3905 error, rather than leaving Windows to report
3906 "file not found" - as the user is probably blissfully
3907 unaware this shim EXE is used, and it will confuse them.
3908 (well, it confused me for a while ;-)
3909 */
3910 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003911 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003912 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003913 "for popen to work with your shell "
3914 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003915 szConsoleSpawn);
3916 return FALSE;
3917 }
3918 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003919 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003920 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003921 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003922
Tim Peters92e4dd82002-10-05 01:47:34 +00003923 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003924 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003925 /* To maintain correct argument passing semantics,
3926 we pass the command-line as it stands, and allow
3927 quoting to be applied. w9xpopen.exe will then
3928 use its argv vector, and re-quote the necessary
3929 args for the ultimate child process.
3930 */
Tim Peters75cdad52001-11-28 22:07:30 +00003931 PyOS_snprintf(
3932 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003933 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003934 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003935 s1,
3936 s3,
3937 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003938 /* Not passing CREATE_NEW_CONSOLE has been known to
3939 cause random failures on win9x. Specifically a
3940 dialog:
3941 "Your program accessed mem currently in use at xxx"
3942 and a hopeful warning about the stability of your
3943 system.
3944 Cost is Ctrl+C wont kill children, but anyone
3945 who cares can have a go!
3946 */
3947 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003948 }
3949 }
3950
3951 /* Could be an else here to try cmd.exe / command.com in the path
3952 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003953 else {
Tim Peters402d5982001-08-27 06:37:48 +00003954 PyErr_SetString(PyExc_RuntimeError,
3955 "Cannot locate a COMSPEC environment variable to "
3956 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003957 return FALSE;
3958 }
Tim Peters5aa91602002-01-30 05:46:57 +00003959
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003960 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3961 siStartInfo.cb = sizeof(STARTUPINFO);
3962 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3963 siStartInfo.hStdInput = hStdin;
3964 siStartInfo.hStdOutput = hStdout;
3965 siStartInfo.hStdError = hStderr;
3966 siStartInfo.wShowWindow = SW_HIDE;
3967
3968 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003969 s2,
3970 NULL,
3971 NULL,
3972 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003973 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003974 NULL,
3975 NULL,
3976 &siStartInfo,
3977 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003978 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003979 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003980
Mark Hammondb37a3732000-08-14 04:47:33 +00003981 /* Return process handle */
3982 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003983 return TRUE;
3984 }
Tim Peters402d5982001-08-27 06:37:48 +00003985 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003986 return FALSE;
3987}
3988
3989/* The following code is based off of KB: Q190351 */
3990
3991static PyObject *
3992_PyPopen(char *cmdstring, int mode, int n)
3993{
3994 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3995 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003996 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003997
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003998 SECURITY_ATTRIBUTES saAttr;
3999 BOOL fSuccess;
4000 int fd1, fd2, fd3;
4001 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004002 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004003 PyObject *f;
4004
4005 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4006 saAttr.bInheritHandle = TRUE;
4007 saAttr.lpSecurityDescriptor = NULL;
4008
4009 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4010 return win32_error("CreatePipe", NULL);
4011
4012 /* Create new output read handle and the input write handle. Set
4013 * the inheritance properties to FALSE. Otherwise, the child inherits
4014 * the these handles; resulting in non-closeable handles to the pipes
4015 * being created. */
4016 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004017 GetCurrentProcess(), &hChildStdinWrDup, 0,
4018 FALSE,
4019 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004020 if (!fSuccess)
4021 return win32_error("DuplicateHandle", NULL);
4022
4023 /* Close the inheritable version of ChildStdin
4024 that we're using. */
4025 CloseHandle(hChildStdinWr);
4026
4027 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4028 return win32_error("CreatePipe", NULL);
4029
4030 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004031 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4032 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004033 if (!fSuccess)
4034 return win32_error("DuplicateHandle", NULL);
4035
4036 /* Close the inheritable version of ChildStdout
4037 that we're using. */
4038 CloseHandle(hChildStdoutRd);
4039
4040 if (n != POPEN_4) {
4041 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4042 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004043 fSuccess = DuplicateHandle(GetCurrentProcess(),
4044 hChildStderrRd,
4045 GetCurrentProcess(),
4046 &hChildStderrRdDup, 0,
4047 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004048 if (!fSuccess)
4049 return win32_error("DuplicateHandle", NULL);
4050 /* Close the inheritable version of ChildStdErr that we're using. */
4051 CloseHandle(hChildStderrRd);
4052 }
Tim Peters5aa91602002-01-30 05:46:57 +00004053
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004054 switch (n) {
4055 case POPEN_1:
4056 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4057 case _O_WRONLY | _O_TEXT:
4058 /* Case for writing to child Stdin in text mode. */
4059 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4060 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004061 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004062 PyFile_SetBufSize(f, 0);
4063 /* We don't care about these pipes anymore, so close them. */
4064 CloseHandle(hChildStdoutRdDup);
4065 CloseHandle(hChildStderrRdDup);
4066 break;
4067
4068 case _O_RDONLY | _O_TEXT:
4069 /* Case for reading from child Stdout in text mode. */
4070 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4071 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004072 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004073 PyFile_SetBufSize(f, 0);
4074 /* We don't care about these pipes anymore, so close them. */
4075 CloseHandle(hChildStdinWrDup);
4076 CloseHandle(hChildStderrRdDup);
4077 break;
4078
4079 case _O_RDONLY | _O_BINARY:
4080 /* Case for readinig from child Stdout in binary mode. */
4081 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4082 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004083 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004084 PyFile_SetBufSize(f, 0);
4085 /* We don't care about these pipes anymore, so close them. */
4086 CloseHandle(hChildStdinWrDup);
4087 CloseHandle(hChildStderrRdDup);
4088 break;
4089
4090 case _O_WRONLY | _O_BINARY:
4091 /* Case for writing to child Stdin in binary mode. */
4092 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4093 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004094 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004095 PyFile_SetBufSize(f, 0);
4096 /* We don't care about these pipes anymore, so close them. */
4097 CloseHandle(hChildStdoutRdDup);
4098 CloseHandle(hChildStderrRdDup);
4099 break;
4100 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004101 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004102 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004103
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004104 case POPEN_2:
4105 case POPEN_4:
4106 {
4107 char *m1, *m2;
4108 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004109
Tim Peters7dca21e2002-08-19 00:42:29 +00004110 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004111 m1 = "r";
4112 m2 = "w";
4113 } else {
4114 m1 = "rb";
4115 m2 = "wb";
4116 }
4117
4118 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4119 f1 = _fdopen(fd1, m2);
4120 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4121 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004122 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004123 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004124 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004125 PyFile_SetBufSize(p2, 0);
4126
4127 if (n != 4)
4128 CloseHandle(hChildStderrRdDup);
4129
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004130 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004131 Py_XDECREF(p1);
4132 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004133 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004134 break;
4135 }
Tim Peters5aa91602002-01-30 05:46:57 +00004136
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004137 case POPEN_3:
4138 {
4139 char *m1, *m2;
4140 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004141
Tim Peters7dca21e2002-08-19 00:42:29 +00004142 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004143 m1 = "r";
4144 m2 = "w";
4145 } else {
4146 m1 = "rb";
4147 m2 = "wb";
4148 }
4149
4150 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4151 f1 = _fdopen(fd1, m2);
4152 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4153 f2 = _fdopen(fd2, m1);
4154 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4155 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004156 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004157 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4158 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004159 PyFile_SetBufSize(p1, 0);
4160 PyFile_SetBufSize(p2, 0);
4161 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004162 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004163 Py_XDECREF(p1);
4164 Py_XDECREF(p2);
4165 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004166 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004167 break;
4168 }
4169 }
4170
4171 if (n == POPEN_4) {
4172 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004173 hChildStdinRd,
4174 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004175 hChildStdoutWr,
4176 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004177 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004178 }
4179 else {
4180 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004181 hChildStdinRd,
4182 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004183 hChildStderrWr,
4184 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004185 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004186 }
4187
Mark Hammondb37a3732000-08-14 04:47:33 +00004188 /*
4189 * Insert the files we've created into the process dictionary
4190 * all referencing the list with the process handle and the
4191 * initial number of files (see description below in _PyPclose).
4192 * Since if _PyPclose later tried to wait on a process when all
4193 * handles weren't closed, it could create a deadlock with the
4194 * child, we spend some energy here to try to ensure that we
4195 * either insert all file handles into the dictionary or none
4196 * at all. It's a little clumsy with the various popen modes
4197 * and variable number of files involved.
4198 */
4199 if (!_PyPopenProcs) {
4200 _PyPopenProcs = PyDict_New();
4201 }
4202
4203 if (_PyPopenProcs) {
4204 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4205 int ins_rc[3];
4206
4207 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4208 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4209
4210 procObj = PyList_New(2);
4211 hProcessObj = PyLong_FromVoidPtr(hProcess);
4212 intObj = PyInt_FromLong(file_count);
4213
4214 if (procObj && hProcessObj && intObj) {
4215 PyList_SetItem(procObj,0,hProcessObj);
4216 PyList_SetItem(procObj,1,intObj);
4217
4218 fileObj[0] = PyLong_FromVoidPtr(f1);
4219 if (fileObj[0]) {
4220 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4221 fileObj[0],
4222 procObj);
4223 }
4224 if (file_count >= 2) {
4225 fileObj[1] = PyLong_FromVoidPtr(f2);
4226 if (fileObj[1]) {
4227 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4228 fileObj[1],
4229 procObj);
4230 }
4231 }
4232 if (file_count >= 3) {
4233 fileObj[2] = PyLong_FromVoidPtr(f3);
4234 if (fileObj[2]) {
4235 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4236 fileObj[2],
4237 procObj);
4238 }
4239 }
4240
4241 if (ins_rc[0] < 0 || !fileObj[0] ||
4242 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4243 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4244 /* Something failed - remove any dictionary
4245 * entries that did make it.
4246 */
4247 if (!ins_rc[0] && fileObj[0]) {
4248 PyDict_DelItem(_PyPopenProcs,
4249 fileObj[0]);
4250 }
4251 if (!ins_rc[1] && fileObj[1]) {
4252 PyDict_DelItem(_PyPopenProcs,
4253 fileObj[1]);
4254 }
4255 if (!ins_rc[2] && fileObj[2]) {
4256 PyDict_DelItem(_PyPopenProcs,
4257 fileObj[2]);
4258 }
4259 }
4260 }
Tim Peters5aa91602002-01-30 05:46:57 +00004261
Mark Hammondb37a3732000-08-14 04:47:33 +00004262 /*
4263 * Clean up our localized references for the dictionary keys
4264 * and value since PyDict_SetItem will Py_INCREF any copies
4265 * that got placed in the dictionary.
4266 */
4267 Py_XDECREF(procObj);
4268 Py_XDECREF(fileObj[0]);
4269 Py_XDECREF(fileObj[1]);
4270 Py_XDECREF(fileObj[2]);
4271 }
4272
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004273 /* Child is launched. Close the parents copy of those pipe
4274 * handles that only the child should have open. You need to
4275 * make sure that no handles to the write end of the output pipe
4276 * are maintained in this process or else the pipe will not close
4277 * when the child process exits and the ReadFile will hang. */
4278
4279 if (!CloseHandle(hChildStdinRd))
4280 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004281
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004282 if (!CloseHandle(hChildStdoutWr))
4283 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004284
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004285 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4286 return win32_error("CloseHandle", NULL);
4287
4288 return f;
4289}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004290
4291/*
4292 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4293 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004294 *
4295 * This function uses the _PyPopenProcs dictionary in order to map the
4296 * input file pointer to information about the process that was
4297 * originally created by the popen* call that created the file pointer.
4298 * The dictionary uses the file pointer as a key (with one entry
4299 * inserted for each file returned by the original popen* call) and a
4300 * single list object as the value for all files from a single call.
4301 * The list object contains the Win32 process handle at [0], and a file
4302 * count at [1], which is initialized to the total number of file
4303 * handles using that list.
4304 *
4305 * This function closes whichever handle it is passed, and decrements
4306 * the file count in the dictionary for the process handle pointed to
4307 * by this file. On the last close (when the file count reaches zero),
4308 * this function will wait for the child process and then return its
4309 * exit code as the result of the close() operation. This permits the
4310 * files to be closed in any order - it is always the close() of the
4311 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004312 *
4313 * NOTE: This function is currently called with the GIL released.
4314 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004315 */
Tim Peters736aa322000-09-01 06:51:24 +00004316
Fredrik Lundh56055a42000-07-23 19:47:12 +00004317static int _PyPclose(FILE *file)
4318{
Fredrik Lundh20318932000-07-26 17:29:12 +00004319 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004320 DWORD exit_code;
4321 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004322 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4323 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004324#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004325 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004326#endif
4327
Fredrik Lundh20318932000-07-26 17:29:12 +00004328 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004329 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004330 */
4331 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004332#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004333 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004334#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004335 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004336 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4337 (procObj = PyDict_GetItem(_PyPopenProcs,
4338 fileObj)) != NULL &&
4339 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4340 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4341
4342 hProcess = PyLong_AsVoidPtr(hProcessObj);
4343 file_count = PyInt_AsLong(intObj);
4344
4345 if (file_count > 1) {
4346 /* Still other files referencing process */
4347 file_count--;
4348 PyList_SetItem(procObj,1,
4349 PyInt_FromLong(file_count));
4350 } else {
4351 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004352 if (result != EOF &&
4353 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4354 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004355 /* Possible truncation here in 16-bit environments, but
4356 * real exit codes are just the lower byte in any event.
4357 */
4358 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004359 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004360 /* Indicate failure - this will cause the file object
4361 * to raise an I/O error and translate the last Win32
4362 * error code from errno. We do have a problem with
4363 * last errors that overlap the normal errno table,
4364 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004365 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004366 if (result != EOF) {
4367 /* If the error wasn't from the fclose(), then
4368 * set errno for the file object error handling.
4369 */
4370 errno = GetLastError();
4371 }
4372 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004373 }
4374
4375 /* Free up the native handle at this point */
4376 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004377 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004378
Mark Hammondb37a3732000-08-14 04:47:33 +00004379 /* Remove this file pointer from dictionary */
4380 PyDict_DelItem(_PyPopenProcs, fileObj);
4381
4382 if (PyDict_Size(_PyPopenProcs) == 0) {
4383 Py_DECREF(_PyPopenProcs);
4384 _PyPopenProcs = NULL;
4385 }
4386
4387 } /* if object retrieval ok */
4388
4389 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004390 } /* if _PyPopenProcs */
4391
Tim Peters736aa322000-09-01 06:51:24 +00004392#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004393 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004394#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004395 return result;
4396}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004397
4398#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004400posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004401{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004402 char *name;
4403 char *mode = "r";
4404 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004405 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004406 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004407 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004408 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004409 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004410 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004411 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004412 if (fp == NULL)
4413 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004414 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004415 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004416 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004417 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004418}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004419
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004420#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004421#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004422
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004423
Guido van Rossumb6775db1994-08-01 11:34:53 +00004424#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004425PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004426"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004427Set the current process's user id.");
4428
Barry Warsaw53699e91996-12-10 23:23:01 +00004429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004430posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004431{
4432 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004433 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004434 return NULL;
4435 if (setuid(uid) < 0)
4436 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004437 Py_INCREF(Py_None);
4438 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004439}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004440#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004442
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004443#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004444PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004445"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004446Set the current process's effective user id.");
4447
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004448static PyObject *
4449posix_seteuid (PyObject *self, PyObject *args)
4450{
4451 int euid;
4452 if (!PyArg_ParseTuple(args, "i", &euid)) {
4453 return NULL;
4454 } else if (seteuid(euid) < 0) {
4455 return posix_error();
4456 } else {
4457 Py_INCREF(Py_None);
4458 return Py_None;
4459 }
4460}
4461#endif /* HAVE_SETEUID */
4462
4463#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004464PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004465"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004466Set the current process's effective group id.");
4467
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004468static PyObject *
4469posix_setegid (PyObject *self, PyObject *args)
4470{
4471 int egid;
4472 if (!PyArg_ParseTuple(args, "i", &egid)) {
4473 return NULL;
4474 } else if (setegid(egid) < 0) {
4475 return posix_error();
4476 } else {
4477 Py_INCREF(Py_None);
4478 return Py_None;
4479 }
4480}
4481#endif /* HAVE_SETEGID */
4482
4483#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004484PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004485"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004486Set the current process's real and effective user ids.");
4487
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004488static PyObject *
4489posix_setreuid (PyObject *self, PyObject *args)
4490{
4491 int ruid, euid;
4492 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4493 return NULL;
4494 } else if (setreuid(ruid, euid) < 0) {
4495 return posix_error();
4496 } else {
4497 Py_INCREF(Py_None);
4498 return Py_None;
4499 }
4500}
4501#endif /* HAVE_SETREUID */
4502
4503#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004504PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004505"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004506Set the current process's real and effective group ids.");
4507
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004508static PyObject *
4509posix_setregid (PyObject *self, PyObject *args)
4510{
4511 int rgid, egid;
4512 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4513 return NULL;
4514 } else if (setregid(rgid, egid) < 0) {
4515 return posix_error();
4516 } else {
4517 Py_INCREF(Py_None);
4518 return Py_None;
4519 }
4520}
4521#endif /* HAVE_SETREGID */
4522
Guido van Rossumb6775db1994-08-01 11:34:53 +00004523#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004524PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004525"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004526Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004527
Barry Warsaw53699e91996-12-10 23:23:01 +00004528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004529posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004530{
4531 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004532 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004533 return NULL;
4534 if (setgid(gid) < 0)
4535 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004536 Py_INCREF(Py_None);
4537 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004538}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004539#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004540
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004541#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004542PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004543"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004544Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004545
4546static PyObject *
4547posix_setgroups(PyObject *self, PyObject *args)
4548{
4549 PyObject *groups;
4550 int i, len;
4551 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004552
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004553 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4554 return NULL;
4555 if (!PySequence_Check(groups)) {
4556 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4557 return NULL;
4558 }
4559 len = PySequence_Size(groups);
4560 if (len > MAX_GROUPS) {
4561 PyErr_SetString(PyExc_ValueError, "too many groups");
4562 return NULL;
4563 }
4564 for(i = 0; i < len; i++) {
4565 PyObject *elem;
4566 elem = PySequence_GetItem(groups, i);
4567 if (!elem)
4568 return NULL;
4569 if (!PyInt_Check(elem)) {
4570 PyErr_SetString(PyExc_TypeError,
4571 "groups must be integers");
4572 Py_DECREF(elem);
4573 return NULL;
4574 }
4575 /* XXX: check that value fits into gid_t. */
4576 grouplist[i] = PyInt_AsLong(elem);
4577 Py_DECREF(elem);
4578 }
4579
4580 if (setgroups(len, grouplist) < 0)
4581 return posix_error();
4582 Py_INCREF(Py_None);
4583 return Py_None;
4584}
4585#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004586
Guido van Rossumb6775db1994-08-01 11:34:53 +00004587#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004588PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004589"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004590Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004591
Barry Warsaw53699e91996-12-10 23:23:01 +00004592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004593posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004594{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004595 int pid, options;
4596#ifdef UNION_WAIT
4597 union wait status;
4598#define status_i (status.w_status)
4599#else
4600 int status;
4601#define status_i status
4602#endif
4603 status_i = 0;
4604
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004605 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004606 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004607 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004608 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004609 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004610 if (pid == -1)
4611 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004612 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004613 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004614}
4615
Tim Petersab034fa2002-02-01 11:27:43 +00004616#elif defined(HAVE_CWAIT)
4617
4618/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004619PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004620"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004621"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004622
4623static PyObject *
4624posix_waitpid(PyObject *self, PyObject *args)
4625{
4626 int pid, options;
4627 int status;
4628
4629 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4630 return NULL;
4631 Py_BEGIN_ALLOW_THREADS
4632 pid = _cwait(&status, pid, options);
4633 Py_END_ALLOW_THREADS
4634 if (pid == -1)
4635 return posix_error();
4636 else
4637 /* shift the status left a byte so this is more like the
4638 POSIX waitpid */
4639 return Py_BuildValue("ii", pid, status << 8);
4640}
4641#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004642
Guido van Rossumad0ee831995-03-01 10:34:45 +00004643#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004644PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004645"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004646Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004647
Barry Warsaw53699e91996-12-10 23:23:01 +00004648static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004649posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004650{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004651 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004652#ifdef UNION_WAIT
4653 union wait status;
4654#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004655#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004656 int status;
4657#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004658#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004659
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004660 status_i = 0;
4661 Py_BEGIN_ALLOW_THREADS
4662 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004663 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004664 if (pid == -1)
4665 return posix_error();
4666 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004667 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004668#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004669}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004670#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004671
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004672
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004673PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004674"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004675Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004676
Barry Warsaw53699e91996-12-10 23:23:01 +00004677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004678posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004679{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004680#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004681 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004682#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004683#ifdef MS_WINDOWS
4684 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4685#else
4686 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4687#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004688#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004689}
4690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004691
Guido van Rossumb6775db1994-08-01 11:34:53 +00004692#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004693PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004694"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004695Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004696
Barry Warsaw53699e91996-12-10 23:23:01 +00004697static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004698posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004699{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004700 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004701 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004702 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004703 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004704 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004705 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004706 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004707 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004708 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004709 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004710 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004711}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004712#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004713
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004714
Guido van Rossumb6775db1994-08-01 11:34:53 +00004715#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004716PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004717"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004718Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004719
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004720static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004721posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004722{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004723 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004724}
4725#endif /* HAVE_SYMLINK */
4726
4727
4728#ifdef HAVE_TIMES
4729#ifndef HZ
4730#define HZ 60 /* Universal constant :-) */
4731#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004732
Guido van Rossumd48f2521997-12-05 22:19:34 +00004733#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4734static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004735system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004736{
4737 ULONG value = 0;
4738
4739 Py_BEGIN_ALLOW_THREADS
4740 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4741 Py_END_ALLOW_THREADS
4742
4743 return value;
4744}
4745
4746static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004747posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004748{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004749 /* Currently Only Uptime is Provided -- Others Later */
4750 return Py_BuildValue("ddddd",
4751 (double)0 /* t.tms_utime / HZ */,
4752 (double)0 /* t.tms_stime / HZ */,
4753 (double)0 /* t.tms_cutime / HZ */,
4754 (double)0 /* t.tms_cstime / HZ */,
4755 (double)system_uptime() / 1000);
4756}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004757#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004758static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004759posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004760{
4761 struct tms t;
4762 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004763 errno = 0;
4764 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004765 if (c == (clock_t) -1)
4766 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004767 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004768 (double)t.tms_utime / HZ,
4769 (double)t.tms_stime / HZ,
4770 (double)t.tms_cutime / HZ,
4771 (double)t.tms_cstime / HZ,
4772 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004773}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004774#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004775#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004776
4777
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004778#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004779#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004780static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004781posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004782{
4783 FILETIME create, exit, kernel, user;
4784 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004785 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004786 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4787 /* The fields of a FILETIME structure are the hi and lo part
4788 of a 64-bit value expressed in 100 nanosecond units.
4789 1e7 is one second in such units; 1e-7 the inverse.
4790 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4791 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004792 return Py_BuildValue(
4793 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004794 (double)(kernel.dwHighDateTime*429.4967296 +
4795 kernel.dwLowDateTime*1e-7),
4796 (double)(user.dwHighDateTime*429.4967296 +
4797 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004798 (double)0,
4799 (double)0,
4800 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004801}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004802#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004803
4804#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004805PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004806"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004807Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004808#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004809
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004810
Guido van Rossumb6775db1994-08-01 11:34:53 +00004811#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004812PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004813"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004814Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004815
Barry Warsaw53699e91996-12-10 23:23:01 +00004816static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004817posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004818{
Guido van Rossum687dd131993-05-17 08:34:16 +00004819 if (setsid() < 0)
4820 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004821 Py_INCREF(Py_None);
4822 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004823}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004824#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004825
Guido van Rossumb6775db1994-08-01 11:34:53 +00004826#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004827PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004828"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004829Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004830
Barry Warsaw53699e91996-12-10 23:23:01 +00004831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004832posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004833{
4834 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004835 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004836 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004837 if (setpgid(pid, pgrp) < 0)
4838 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004839 Py_INCREF(Py_None);
4840 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004841}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004842#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004843
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004844
Guido van Rossumb6775db1994-08-01 11:34:53 +00004845#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004846PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004847"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004848Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004849
Barry Warsaw53699e91996-12-10 23:23:01 +00004850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004851posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004852{
4853 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004854 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004855 return NULL;
4856 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004857 if (pgid < 0)
4858 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004859 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004860}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004861#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004863
Guido van Rossumb6775db1994-08-01 11:34:53 +00004864#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004865PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004866"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004867Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004868
Barry Warsaw53699e91996-12-10 23:23:01 +00004869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004870posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004871{
4872 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004873 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004874 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004875 if (tcsetpgrp(fd, pgid) < 0)
4876 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004877 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004878 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004879}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004880#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004881
Guido van Rossum687dd131993-05-17 08:34:16 +00004882/* Functions acting on file descriptors */
4883
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004884PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004885"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004886Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004887
Barry Warsaw53699e91996-12-10 23:23:01 +00004888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004889posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004890{
Mark Hammondef8b6542001-05-13 08:04:26 +00004891 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004892 int flag;
4893 int mode = 0777;
4894 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004895
4896#ifdef MS_WINDOWS
4897 if (unicode_file_names()) {
4898 PyUnicodeObject *po;
4899 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4900 Py_BEGIN_ALLOW_THREADS
4901 /* PyUnicode_AS_UNICODE OK without thread
4902 lock as it is a simple dereference. */
4903 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4904 Py_END_ALLOW_THREADS
4905 if (fd < 0)
4906 return posix_error();
4907 return PyInt_FromLong((long)fd);
4908 }
4909 /* Drop the argument parsing error as narrow strings
4910 are also valid. */
4911 PyErr_Clear();
4912 }
4913#endif
4914
Tim Peters5aa91602002-01-30 05:46:57 +00004915 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004916 Py_FileSystemDefaultEncoding, &file,
4917 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004918 return NULL;
4919
Barry Warsaw53699e91996-12-10 23:23:01 +00004920 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004921 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004922 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004923 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004924 return posix_error_with_allocated_filename(file);
4925 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004926 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004927}
4928
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004929
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004930PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004931"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004932Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004933
Barry Warsaw53699e91996-12-10 23:23:01 +00004934static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004935posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004936{
4937 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004938 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004939 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004940 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004941 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004942 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004943 if (res < 0)
4944 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004945 Py_INCREF(Py_None);
4946 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004947}
4948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004949
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004950PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004951"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004952Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004953
Barry Warsaw53699e91996-12-10 23:23:01 +00004954static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004955posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004956{
4957 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004958 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004959 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004960 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004961 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004962 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004963 if (fd < 0)
4964 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004965 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004966}
4967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004968
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004969PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004970"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004971Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004972
Barry Warsaw53699e91996-12-10 23:23:01 +00004973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004974posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004975{
4976 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004977 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004978 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004979 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004980 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004981 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004982 if (res < 0)
4983 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004984 Py_INCREF(Py_None);
4985 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004986}
4987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004988
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004989PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004990"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004991Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004992
Barry Warsaw53699e91996-12-10 23:23:01 +00004993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004994posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004995{
4996 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004997#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004998 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004999#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005000 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005001#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005002 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005003 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005004 return NULL;
5005#ifdef SEEK_SET
5006 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5007 switch (how) {
5008 case 0: how = SEEK_SET; break;
5009 case 1: how = SEEK_CUR; break;
5010 case 2: how = SEEK_END; break;
5011 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005012#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005013
5014#if !defined(HAVE_LARGEFILE_SUPPORT)
5015 pos = PyInt_AsLong(posobj);
5016#else
5017 pos = PyLong_Check(posobj) ?
5018 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5019#endif
5020 if (PyErr_Occurred())
5021 return NULL;
5022
Barry Warsaw53699e91996-12-10 23:23:01 +00005023 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005024#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005025 res = _lseeki64(fd, pos, how);
5026#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005027 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005028#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005029 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005030 if (res < 0)
5031 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005032
5033#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005034 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005035#else
5036 return PyLong_FromLongLong(res);
5037#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005038}
5039
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005040
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005041PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005042"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005043Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005044
Barry Warsaw53699e91996-12-10 23:23:01 +00005045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005046posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005047{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005048 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005049 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005050 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005051 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005052 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005053 if (buffer == NULL)
5054 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005055 Py_BEGIN_ALLOW_THREADS
5056 n = read(fd, PyString_AsString(buffer), size);
5057 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005058 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005059 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005060 return posix_error();
5061 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005062 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005063 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005064 return buffer;
5065}
5066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005068PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005069"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005070Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005071
Barry Warsaw53699e91996-12-10 23:23:01 +00005072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005073posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005074{
5075 int fd, size;
5076 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005077 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005078 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005079 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005080 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005081 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005082 if (size < 0)
5083 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005084 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005085}
5086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005087
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005088PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005089"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005090Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005091
Barry Warsaw53699e91996-12-10 23:23:01 +00005092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005093posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005094{
5095 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005096 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005097 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005098 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005099 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005100#ifdef __VMS
5101 /* on OpenVMS we must ensure that all bytes are written to the file */
5102 fsync(fd);
5103#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005104 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005105 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005106 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005107 if (res != 0)
5108 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005109
Fred Drake699f3522000-06-29 21:12:41 +00005110 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005111}
5112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005113
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005114PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005115"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005116Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005117
Barry Warsaw53699e91996-12-10 23:23:01 +00005118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005119posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005120{
Guido van Rossum687dd131993-05-17 08:34:16 +00005121 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005122 char *mode = "r";
5123 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005124 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005125 PyObject *f;
5126 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005127 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005128
Thomas Heller1f043e22002-11-07 16:00:59 +00005129 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5130 PyErr_Format(PyExc_ValueError,
5131 "invalid file mode '%s'", mode);
5132 return NULL;
5133 }
5134
Barry Warsaw53699e91996-12-10 23:23:01 +00005135 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005136 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005137 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005138 if (fp == NULL)
5139 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005140 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005141 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005142 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005143 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005144}
5145
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005146PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005147"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005148Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005149connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005150
5151static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005152posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005153{
5154 int fd;
5155 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5156 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005157 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005158}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005159
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005160#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005161PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005162"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005163Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005164
Barry Warsaw53699e91996-12-10 23:23:01 +00005165static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005166posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005167{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005168#if defined(PYOS_OS2)
5169 HFILE read, write;
5170 APIRET rc;
5171
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005172 Py_BEGIN_ALLOW_THREADS
5173 rc = DosCreatePipe( &read, &write, 4096);
5174 Py_END_ALLOW_THREADS
5175 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005176 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005177
5178 return Py_BuildValue("(ii)", read, write);
5179#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005180#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005181 int fds[2];
5182 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005183 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005184#if defined(__VMS)
5185 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5186#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005187 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005188#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005189 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005190 if (res != 0)
5191 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005192 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005193#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005194 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005195 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005196 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005197 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005198 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005199 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005200 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005201 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005202 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5203 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005204 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005205#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005206#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005207}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005208#endif /* HAVE_PIPE */
5209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005210
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005211#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005212PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005213"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005214Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005215
Barry Warsaw53699e91996-12-10 23:23:01 +00005216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005217posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005218{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005219 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005220 int mode = 0666;
5221 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005222 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005223 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005224 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005225 res = mkfifo(filename, mode);
5226 Py_END_ALLOW_THREADS
5227 if (res < 0)
5228 return posix_error();
5229 Py_INCREF(Py_None);
5230 return Py_None;
5231}
5232#endif
5233
5234
Neal Norwitz11690112002-07-30 01:08:28 +00005235#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005236PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005237"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005238Create a filesystem node (file, device special file or named pipe)\n\
5239named filename. mode specifies both the permissions to use and the\n\
5240type of node to be created, being combined (bitwise OR) with one of\n\
5241S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005242device defines the newly created device special file (probably using\n\
5243os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005244
5245
5246static PyObject *
5247posix_mknod(PyObject *self, PyObject *args)
5248{
5249 char *filename;
5250 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005251 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005252 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005253 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005254 return NULL;
5255 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005256 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005257 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005258 if (res < 0)
5259 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005260 Py_INCREF(Py_None);
5261 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005262}
5263#endif
5264
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005265#ifdef HAVE_DEVICE_MACROS
5266PyDoc_STRVAR(posix_major__doc__,
5267"major(device) -> major number\n\
5268Extracts a device major number from a raw device number.");
5269
5270static PyObject *
5271posix_major(PyObject *self, PyObject *args)
5272{
5273 int device;
5274 if (!PyArg_ParseTuple(args, "i:major", &device))
5275 return NULL;
5276 return PyInt_FromLong((long)major(device));
5277}
5278
5279PyDoc_STRVAR(posix_minor__doc__,
5280"minor(device) -> minor number\n\
5281Extracts a device minor number from a raw device number.");
5282
5283static PyObject *
5284posix_minor(PyObject *self, PyObject *args)
5285{
5286 int device;
5287 if (!PyArg_ParseTuple(args, "i:minor", &device))
5288 return NULL;
5289 return PyInt_FromLong((long)minor(device));
5290}
5291
5292PyDoc_STRVAR(posix_makedev__doc__,
5293"makedev(major, minor) -> device number\n\
5294Composes a raw device number from the major and minor device numbers.");
5295
5296static PyObject *
5297posix_makedev(PyObject *self, PyObject *args)
5298{
5299 int major, minor;
5300 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5301 return NULL;
5302 return PyInt_FromLong((long)makedev(major, minor));
5303}
5304#endif /* device macros */
5305
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005306
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005307#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005308PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005309"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005310Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005311
Barry Warsaw53699e91996-12-10 23:23:01 +00005312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005313posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005314{
5315 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005316 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005317 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005318 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005319
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005320 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005321 return NULL;
5322
5323#if !defined(HAVE_LARGEFILE_SUPPORT)
5324 length = PyInt_AsLong(lenobj);
5325#else
5326 length = PyLong_Check(lenobj) ?
5327 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5328#endif
5329 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005330 return NULL;
5331
Barry Warsaw53699e91996-12-10 23:23:01 +00005332 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005333 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005334 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005335 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005336 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005337 return NULL;
5338 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005339 Py_INCREF(Py_None);
5340 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005341}
5342#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005343
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005344#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005345PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005346"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005347Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005348
Fred Drake762e2061999-08-26 17:23:54 +00005349/* Save putenv() parameters as values here, so we can collect them when they
5350 * get re-set with another call for the same key. */
5351static PyObject *posix_putenv_garbage;
5352
Tim Peters5aa91602002-01-30 05:46:57 +00005353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005354posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005355{
5356 char *s1, *s2;
5357 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005358 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005359 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005360
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005361 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005362 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005363
5364#if defined(PYOS_OS2)
5365 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5366 APIRET rc;
5367
Guido van Rossumd48f2521997-12-05 22:19:34 +00005368 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5369 if (rc != NO_ERROR)
5370 return os2_error(rc);
5371
5372 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5373 APIRET rc;
5374
Guido van Rossumd48f2521997-12-05 22:19:34 +00005375 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5376 if (rc != NO_ERROR)
5377 return os2_error(rc);
5378 } else {
5379#endif
5380
Fred Drake762e2061999-08-26 17:23:54 +00005381 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005382 len = strlen(s1) + strlen(s2) + 2;
5383 /* len includes space for a trailing \0; the size arg to
5384 PyString_FromStringAndSize does not count that */
5385 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005386 if (newstr == NULL)
5387 return PyErr_NoMemory();
5388 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005389 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005390 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005391 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005392 posix_error();
5393 return NULL;
5394 }
Fred Drake762e2061999-08-26 17:23:54 +00005395 /* Install the first arg and newstr in posix_putenv_garbage;
5396 * this will cause previous value to be collected. This has to
5397 * happen after the real putenv() call because the old value
5398 * was still accessible until then. */
5399 if (PyDict_SetItem(posix_putenv_garbage,
5400 PyTuple_GET_ITEM(args, 0), newstr)) {
5401 /* really not much we can do; just leak */
5402 PyErr_Clear();
5403 }
5404 else {
5405 Py_DECREF(newstr);
5406 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005407
5408#if defined(PYOS_OS2)
5409 }
5410#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005411 Py_INCREF(Py_None);
5412 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005413}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005414#endif /* putenv */
5415
Guido van Rossumc524d952001-10-19 01:31:59 +00005416#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005417PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005418"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005419Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005420
5421static PyObject *
5422posix_unsetenv(PyObject *self, PyObject *args)
5423{
5424 char *s1;
5425
5426 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5427 return NULL;
5428
5429 unsetenv(s1);
5430
5431 /* Remove the key from posix_putenv_garbage;
5432 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005433 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005434 * old value was still accessible until then.
5435 */
5436 if (PyDict_DelItem(posix_putenv_garbage,
5437 PyTuple_GET_ITEM(args, 0))) {
5438 /* really not much we can do; just leak */
5439 PyErr_Clear();
5440 }
5441
5442 Py_INCREF(Py_None);
5443 return Py_None;
5444}
5445#endif /* unsetenv */
5446
Guido van Rossumb6a47161997-09-15 22:54:34 +00005447#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005448PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005449"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005450Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005451
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005453posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005454{
5455 int code;
5456 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005457 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005458 return NULL;
5459 message = strerror(code);
5460 if (message == NULL) {
5461 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005462 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005463 return NULL;
5464 }
5465 return PyString_FromString(message);
5466}
5467#endif /* strerror */
5468
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005469
Guido van Rossumc9641791998-08-04 15:26:23 +00005470#ifdef HAVE_SYS_WAIT_H
5471
Fred Drake106c1a02002-04-23 15:58:02 +00005472#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005473PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005474"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005475Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005476
5477static PyObject *
5478posix_WCOREDUMP(PyObject *self, PyObject *args)
5479{
5480#ifdef UNION_WAIT
5481 union wait status;
5482#define status_i (status.w_status)
5483#else
5484 int status;
5485#define status_i status
5486#endif
5487 status_i = 0;
5488
5489 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5490 {
5491 return NULL;
5492 }
5493
5494 return PyBool_FromLong(WCOREDUMP(status));
5495#undef status_i
5496}
5497#endif /* WCOREDUMP */
5498
5499#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005500PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005501"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005502Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005503job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005504
5505static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005506posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005507{
5508#ifdef UNION_WAIT
5509 union wait status;
5510#define status_i (status.w_status)
5511#else
5512 int status;
5513#define status_i status
5514#endif
5515 status_i = 0;
5516
5517 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5518 {
5519 return NULL;
5520 }
5521
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005522 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005523#undef status_i
5524}
5525#endif /* WIFCONTINUED */
5526
Guido van Rossumc9641791998-08-04 15:26:23 +00005527#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005528PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005529"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005530Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005531
5532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005533posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005534{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005535#ifdef UNION_WAIT
5536 union wait status;
5537#define status_i (status.w_status)
5538#else
5539 int status;
5540#define status_i status
5541#endif
5542 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005543
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005544 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005545 {
5546 return NULL;
5547 }
Tim Peters5aa91602002-01-30 05:46:57 +00005548
Fred Drake106c1a02002-04-23 15:58:02 +00005549 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005550#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005551}
5552#endif /* WIFSTOPPED */
5553
5554#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005555PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005556"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005558
5559static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005560posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005561{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005562#ifdef UNION_WAIT
5563 union wait status;
5564#define status_i (status.w_status)
5565#else
5566 int status;
5567#define status_i status
5568#endif
5569 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005570
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005571 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005572 {
5573 return NULL;
5574 }
Tim Peters5aa91602002-01-30 05:46:57 +00005575
Fred Drake106c1a02002-04-23 15:58:02 +00005576 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005577#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005578}
5579#endif /* WIFSIGNALED */
5580
5581#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005582PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005583"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005584Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005585system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005586
5587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005588posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005589{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005590#ifdef UNION_WAIT
5591 union wait status;
5592#define status_i (status.w_status)
5593#else
5594 int status;
5595#define status_i status
5596#endif
5597 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005598
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005599 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005600 {
5601 return NULL;
5602 }
Tim Peters5aa91602002-01-30 05:46:57 +00005603
Fred Drake106c1a02002-04-23 15:58:02 +00005604 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005605#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005606}
5607#endif /* WIFEXITED */
5608
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005609#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005610PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005611"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005612Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005613
5614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005615posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005616{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005617#ifdef UNION_WAIT
5618 union wait status;
5619#define status_i (status.w_status)
5620#else
5621 int status;
5622#define status_i status
5623#endif
5624 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005625
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005626 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005627 {
5628 return NULL;
5629 }
Tim Peters5aa91602002-01-30 05:46:57 +00005630
Guido van Rossumc9641791998-08-04 15:26:23 +00005631 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005632#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005633}
5634#endif /* WEXITSTATUS */
5635
5636#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005637PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005638"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005639Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005640value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005641
5642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005643posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005644{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005645#ifdef UNION_WAIT
5646 union wait status;
5647#define status_i (status.w_status)
5648#else
5649 int status;
5650#define status_i status
5651#endif
5652 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005653
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005654 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005655 {
5656 return NULL;
5657 }
Tim Peters5aa91602002-01-30 05:46:57 +00005658
Guido van Rossumc9641791998-08-04 15:26:23 +00005659 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005660#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005661}
5662#endif /* WTERMSIG */
5663
5664#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005665PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005666"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667Return the signal that stopped the process that provided\n\
5668the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005669
5670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005671posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005672{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005673#ifdef UNION_WAIT
5674 union wait status;
5675#define status_i (status.w_status)
5676#else
5677 int status;
5678#define status_i status
5679#endif
5680 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005681
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005682 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005683 {
5684 return NULL;
5685 }
Tim Peters5aa91602002-01-30 05:46:57 +00005686
Guido van Rossumc9641791998-08-04 15:26:23 +00005687 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005688#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005689}
5690#endif /* WSTOPSIG */
5691
5692#endif /* HAVE_SYS_WAIT_H */
5693
5694
Guido van Rossum94f6f721999-01-06 18:42:14 +00005695#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005696#ifdef _SCO_DS
5697/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5698 needed definitions in sys/statvfs.h */
5699#define _SVID3
5700#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005701#include <sys/statvfs.h>
5702
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005703static PyObject*
5704_pystatvfs_fromstructstatvfs(struct statvfs st) {
5705 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5706 if (v == NULL)
5707 return NULL;
5708
5709#if !defined(HAVE_LARGEFILE_SUPPORT)
5710 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5711 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5712 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5713 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5714 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5715 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5716 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5717 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5718 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5719 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5720#else
5721 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5722 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005723 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005724 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005725 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005726 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005727 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005728 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005729 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005730 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005731 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005732 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005733 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005734 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005735 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5736 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5737#endif
5738
5739 return v;
5740}
5741
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005742PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005743"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005744Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005745
5746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005747posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005748{
5749 int fd, res;
5750 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005751
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005752 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005753 return NULL;
5754 Py_BEGIN_ALLOW_THREADS
5755 res = fstatvfs(fd, &st);
5756 Py_END_ALLOW_THREADS
5757 if (res != 0)
5758 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005759
5760 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005761}
5762#endif /* HAVE_FSTATVFS */
5763
5764
5765#if defined(HAVE_STATVFS)
5766#include <sys/statvfs.h>
5767
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005768PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005769"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005770Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005771
5772static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005773posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005774{
5775 char *path;
5776 int res;
5777 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005778 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005779 return NULL;
5780 Py_BEGIN_ALLOW_THREADS
5781 res = statvfs(path, &st);
5782 Py_END_ALLOW_THREADS
5783 if (res != 0)
5784 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005785
5786 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005787}
5788#endif /* HAVE_STATVFS */
5789
5790
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005791#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005792PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005793"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005794Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005795The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005796or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005797
5798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005799posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005800{
5801 PyObject *result = NULL;
5802 char *dir = NULL;
5803 char *pfx = NULL;
5804 char *name;
5805
5806 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5807 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005808
5809 if (PyErr_Warn(PyExc_RuntimeWarning,
5810 "tempnam is a potential security risk to your program") < 0)
5811 return NULL;
5812
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005813#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005814 name = _tempnam(dir, pfx);
5815#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005816 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005817#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005818 if (name == NULL)
5819 return PyErr_NoMemory();
5820 result = PyString_FromString(name);
5821 free(name);
5822 return result;
5823}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005824#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005825
5826
5827#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005828PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005829"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005830Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005831
5832static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005833posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005834{
5835 FILE *fp;
5836
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005837 fp = tmpfile();
5838 if (fp == NULL)
5839 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005840 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005841}
5842#endif
5843
5844
5845#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005846PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005847"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005848Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005849
5850static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005851posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005852{
5853 char buffer[L_tmpnam];
5854 char *name;
5855
Skip Montanaro95618b52001-08-18 18:52:10 +00005856 if (PyErr_Warn(PyExc_RuntimeWarning,
5857 "tmpnam is a potential security risk to your program") < 0)
5858 return NULL;
5859
Greg Wardb48bc172000-03-01 21:51:56 +00005860#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005861 name = tmpnam_r(buffer);
5862#else
5863 name = tmpnam(buffer);
5864#endif
5865 if (name == NULL) {
5866 PyErr_SetObject(PyExc_OSError,
5867 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005868#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005869 "unexpected NULL from tmpnam_r"
5870#else
5871 "unexpected NULL from tmpnam"
5872#endif
5873 ));
5874 return NULL;
5875 }
5876 return PyString_FromString(buffer);
5877}
5878#endif
5879
5880
Fred Drakec9680921999-12-13 16:37:25 +00005881/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5882 * It maps strings representing configuration variable names to
5883 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005884 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005885 * rarely-used constants. There are three separate tables that use
5886 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005887 *
5888 * This code is always included, even if none of the interfaces that
5889 * need it are included. The #if hackery needed to avoid it would be
5890 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005891 */
5892struct constdef {
5893 char *name;
5894 long value;
5895};
5896
Fred Drake12c6e2d1999-12-14 21:25:03 +00005897static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005898conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5899 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005900{
5901 if (PyInt_Check(arg)) {
5902 *valuep = PyInt_AS_LONG(arg);
5903 return 1;
5904 }
5905 if (PyString_Check(arg)) {
5906 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005907 size_t lo = 0;
5908 size_t mid;
5909 size_t hi = tablesize;
5910 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005911 char *confname = PyString_AS_STRING(arg);
5912 while (lo < hi) {
5913 mid = (lo + hi) / 2;
5914 cmp = strcmp(confname, table[mid].name);
5915 if (cmp < 0)
5916 hi = mid;
5917 else if (cmp > 0)
5918 lo = mid + 1;
5919 else {
5920 *valuep = table[mid].value;
5921 return 1;
5922 }
5923 }
5924 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5925 }
5926 else
5927 PyErr_SetString(PyExc_TypeError,
5928 "configuration names must be strings or integers");
5929 return 0;
5930}
5931
5932
5933#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5934static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005935#ifdef _PC_ABI_AIO_XFER_MAX
5936 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5937#endif
5938#ifdef _PC_ABI_ASYNC_IO
5939 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5940#endif
Fred Drakec9680921999-12-13 16:37:25 +00005941#ifdef _PC_ASYNC_IO
5942 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5943#endif
5944#ifdef _PC_CHOWN_RESTRICTED
5945 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5946#endif
5947#ifdef _PC_FILESIZEBITS
5948 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5949#endif
5950#ifdef _PC_LAST
5951 {"PC_LAST", _PC_LAST},
5952#endif
5953#ifdef _PC_LINK_MAX
5954 {"PC_LINK_MAX", _PC_LINK_MAX},
5955#endif
5956#ifdef _PC_MAX_CANON
5957 {"PC_MAX_CANON", _PC_MAX_CANON},
5958#endif
5959#ifdef _PC_MAX_INPUT
5960 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5961#endif
5962#ifdef _PC_NAME_MAX
5963 {"PC_NAME_MAX", _PC_NAME_MAX},
5964#endif
5965#ifdef _PC_NO_TRUNC
5966 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5967#endif
5968#ifdef _PC_PATH_MAX
5969 {"PC_PATH_MAX", _PC_PATH_MAX},
5970#endif
5971#ifdef _PC_PIPE_BUF
5972 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5973#endif
5974#ifdef _PC_PRIO_IO
5975 {"PC_PRIO_IO", _PC_PRIO_IO},
5976#endif
5977#ifdef _PC_SOCK_MAXBUF
5978 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5979#endif
5980#ifdef _PC_SYNC_IO
5981 {"PC_SYNC_IO", _PC_SYNC_IO},
5982#endif
5983#ifdef _PC_VDISABLE
5984 {"PC_VDISABLE", _PC_VDISABLE},
5985#endif
5986};
5987
Fred Drakec9680921999-12-13 16:37:25 +00005988static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005989conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005990{
5991 return conv_confname(arg, valuep, posix_constants_pathconf,
5992 sizeof(posix_constants_pathconf)
5993 / sizeof(struct constdef));
5994}
5995#endif
5996
5997#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005998PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005999"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006000Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006001If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006002
6003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006004posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006005{
6006 PyObject *result = NULL;
6007 int name, fd;
6008
Fred Drake12c6e2d1999-12-14 21:25:03 +00006009 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6010 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006011 long limit;
6012
6013 errno = 0;
6014 limit = fpathconf(fd, name);
6015 if (limit == -1 && errno != 0)
6016 posix_error();
6017 else
6018 result = PyInt_FromLong(limit);
6019 }
6020 return result;
6021}
6022#endif
6023
6024
6025#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006026PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006027"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006028Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006029If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006030
6031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006032posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006033{
6034 PyObject *result = NULL;
6035 int name;
6036 char *path;
6037
6038 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6039 conv_path_confname, &name)) {
6040 long limit;
6041
6042 errno = 0;
6043 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006044 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006045 if (errno == EINVAL)
6046 /* could be a path or name problem */
6047 posix_error();
6048 else
6049 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006050 }
Fred Drakec9680921999-12-13 16:37:25 +00006051 else
6052 result = PyInt_FromLong(limit);
6053 }
6054 return result;
6055}
6056#endif
6057
6058#ifdef HAVE_CONFSTR
6059static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006060#ifdef _CS_ARCHITECTURE
6061 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6062#endif
6063#ifdef _CS_HOSTNAME
6064 {"CS_HOSTNAME", _CS_HOSTNAME},
6065#endif
6066#ifdef _CS_HW_PROVIDER
6067 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6068#endif
6069#ifdef _CS_HW_SERIAL
6070 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6071#endif
6072#ifdef _CS_INITTAB_NAME
6073 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6074#endif
Fred Drakec9680921999-12-13 16:37:25 +00006075#ifdef _CS_LFS64_CFLAGS
6076 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6077#endif
6078#ifdef _CS_LFS64_LDFLAGS
6079 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6080#endif
6081#ifdef _CS_LFS64_LIBS
6082 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6083#endif
6084#ifdef _CS_LFS64_LINTFLAGS
6085 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6086#endif
6087#ifdef _CS_LFS_CFLAGS
6088 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6089#endif
6090#ifdef _CS_LFS_LDFLAGS
6091 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6092#endif
6093#ifdef _CS_LFS_LIBS
6094 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6095#endif
6096#ifdef _CS_LFS_LINTFLAGS
6097 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6098#endif
Fred Draked86ed291999-12-15 15:34:33 +00006099#ifdef _CS_MACHINE
6100 {"CS_MACHINE", _CS_MACHINE},
6101#endif
Fred Drakec9680921999-12-13 16:37:25 +00006102#ifdef _CS_PATH
6103 {"CS_PATH", _CS_PATH},
6104#endif
Fred Draked86ed291999-12-15 15:34:33 +00006105#ifdef _CS_RELEASE
6106 {"CS_RELEASE", _CS_RELEASE},
6107#endif
6108#ifdef _CS_SRPC_DOMAIN
6109 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6110#endif
6111#ifdef _CS_SYSNAME
6112 {"CS_SYSNAME", _CS_SYSNAME},
6113#endif
6114#ifdef _CS_VERSION
6115 {"CS_VERSION", _CS_VERSION},
6116#endif
Fred Drakec9680921999-12-13 16:37:25 +00006117#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6118 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6119#endif
6120#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6121 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6122#endif
6123#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6124 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6125#endif
6126#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6127 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6128#endif
6129#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6130 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6131#endif
6132#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6133 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6134#endif
6135#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6136 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6137#endif
6138#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6139 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6140#endif
6141#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6142 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6143#endif
6144#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6145 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6146#endif
6147#ifdef _CS_XBS5_LP64_OFF64_LIBS
6148 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6149#endif
6150#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6151 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6152#endif
6153#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6154 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6155#endif
6156#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6157 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6158#endif
6159#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6160 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6161#endif
6162#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6163 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6164#endif
Fred Draked86ed291999-12-15 15:34:33 +00006165#ifdef _MIPS_CS_AVAIL_PROCESSORS
6166 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6167#endif
6168#ifdef _MIPS_CS_BASE
6169 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6170#endif
6171#ifdef _MIPS_CS_HOSTID
6172 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6173#endif
6174#ifdef _MIPS_CS_HW_NAME
6175 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6176#endif
6177#ifdef _MIPS_CS_NUM_PROCESSORS
6178 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6179#endif
6180#ifdef _MIPS_CS_OSREL_MAJ
6181 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6182#endif
6183#ifdef _MIPS_CS_OSREL_MIN
6184 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6185#endif
6186#ifdef _MIPS_CS_OSREL_PATCH
6187 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6188#endif
6189#ifdef _MIPS_CS_OS_NAME
6190 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6191#endif
6192#ifdef _MIPS_CS_OS_PROVIDER
6193 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6194#endif
6195#ifdef _MIPS_CS_PROCESSORS
6196 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6197#endif
6198#ifdef _MIPS_CS_SERIAL
6199 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6200#endif
6201#ifdef _MIPS_CS_VENDOR
6202 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6203#endif
Fred Drakec9680921999-12-13 16:37:25 +00006204};
6205
6206static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006207conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006208{
6209 return conv_confname(arg, valuep, posix_constants_confstr,
6210 sizeof(posix_constants_confstr)
6211 / sizeof(struct constdef));
6212}
6213
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006214PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006215"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006216Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006217
6218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006219posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006220{
6221 PyObject *result = NULL;
6222 int name;
6223 char buffer[64];
6224
6225 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6226 int len = confstr(name, buffer, sizeof(buffer));
6227
Fred Drakec9680921999-12-13 16:37:25 +00006228 errno = 0;
6229 if (len == 0) {
6230 if (errno != 0)
6231 posix_error();
6232 else
6233 result = PyString_FromString("");
6234 }
6235 else {
6236 if (len >= sizeof(buffer)) {
6237 result = PyString_FromStringAndSize(NULL, len);
6238 if (result != NULL)
6239 confstr(name, PyString_AS_STRING(result), len+1);
6240 }
6241 else
6242 result = PyString_FromString(buffer);
6243 }
6244 }
6245 return result;
6246}
6247#endif
6248
6249
6250#ifdef HAVE_SYSCONF
6251static struct constdef posix_constants_sysconf[] = {
6252#ifdef _SC_2_CHAR_TERM
6253 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6254#endif
6255#ifdef _SC_2_C_BIND
6256 {"SC_2_C_BIND", _SC_2_C_BIND},
6257#endif
6258#ifdef _SC_2_C_DEV
6259 {"SC_2_C_DEV", _SC_2_C_DEV},
6260#endif
6261#ifdef _SC_2_C_VERSION
6262 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6263#endif
6264#ifdef _SC_2_FORT_DEV
6265 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6266#endif
6267#ifdef _SC_2_FORT_RUN
6268 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6269#endif
6270#ifdef _SC_2_LOCALEDEF
6271 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6272#endif
6273#ifdef _SC_2_SW_DEV
6274 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6275#endif
6276#ifdef _SC_2_UPE
6277 {"SC_2_UPE", _SC_2_UPE},
6278#endif
6279#ifdef _SC_2_VERSION
6280 {"SC_2_VERSION", _SC_2_VERSION},
6281#endif
Fred Draked86ed291999-12-15 15:34:33 +00006282#ifdef _SC_ABI_ASYNCHRONOUS_IO
6283 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6284#endif
6285#ifdef _SC_ACL
6286 {"SC_ACL", _SC_ACL},
6287#endif
Fred Drakec9680921999-12-13 16:37:25 +00006288#ifdef _SC_AIO_LISTIO_MAX
6289 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6290#endif
Fred Drakec9680921999-12-13 16:37:25 +00006291#ifdef _SC_AIO_MAX
6292 {"SC_AIO_MAX", _SC_AIO_MAX},
6293#endif
6294#ifdef _SC_AIO_PRIO_DELTA_MAX
6295 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6296#endif
6297#ifdef _SC_ARG_MAX
6298 {"SC_ARG_MAX", _SC_ARG_MAX},
6299#endif
6300#ifdef _SC_ASYNCHRONOUS_IO
6301 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6302#endif
6303#ifdef _SC_ATEXIT_MAX
6304 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6305#endif
Fred Draked86ed291999-12-15 15:34:33 +00006306#ifdef _SC_AUDIT
6307 {"SC_AUDIT", _SC_AUDIT},
6308#endif
Fred Drakec9680921999-12-13 16:37:25 +00006309#ifdef _SC_AVPHYS_PAGES
6310 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6311#endif
6312#ifdef _SC_BC_BASE_MAX
6313 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6314#endif
6315#ifdef _SC_BC_DIM_MAX
6316 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6317#endif
6318#ifdef _SC_BC_SCALE_MAX
6319 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6320#endif
6321#ifdef _SC_BC_STRING_MAX
6322 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6323#endif
Fred Draked86ed291999-12-15 15:34:33 +00006324#ifdef _SC_CAP
6325 {"SC_CAP", _SC_CAP},
6326#endif
Fred Drakec9680921999-12-13 16:37:25 +00006327#ifdef _SC_CHARCLASS_NAME_MAX
6328 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6329#endif
6330#ifdef _SC_CHAR_BIT
6331 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6332#endif
6333#ifdef _SC_CHAR_MAX
6334 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6335#endif
6336#ifdef _SC_CHAR_MIN
6337 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6338#endif
6339#ifdef _SC_CHILD_MAX
6340 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6341#endif
6342#ifdef _SC_CLK_TCK
6343 {"SC_CLK_TCK", _SC_CLK_TCK},
6344#endif
6345#ifdef _SC_COHER_BLKSZ
6346 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6347#endif
6348#ifdef _SC_COLL_WEIGHTS_MAX
6349 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6350#endif
6351#ifdef _SC_DCACHE_ASSOC
6352 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6353#endif
6354#ifdef _SC_DCACHE_BLKSZ
6355 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6356#endif
6357#ifdef _SC_DCACHE_LINESZ
6358 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6359#endif
6360#ifdef _SC_DCACHE_SZ
6361 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6362#endif
6363#ifdef _SC_DCACHE_TBLKSZ
6364 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6365#endif
6366#ifdef _SC_DELAYTIMER_MAX
6367 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6368#endif
6369#ifdef _SC_EQUIV_CLASS_MAX
6370 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6371#endif
6372#ifdef _SC_EXPR_NEST_MAX
6373 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6374#endif
6375#ifdef _SC_FSYNC
6376 {"SC_FSYNC", _SC_FSYNC},
6377#endif
6378#ifdef _SC_GETGR_R_SIZE_MAX
6379 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6380#endif
6381#ifdef _SC_GETPW_R_SIZE_MAX
6382 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6383#endif
6384#ifdef _SC_ICACHE_ASSOC
6385 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6386#endif
6387#ifdef _SC_ICACHE_BLKSZ
6388 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6389#endif
6390#ifdef _SC_ICACHE_LINESZ
6391 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6392#endif
6393#ifdef _SC_ICACHE_SZ
6394 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6395#endif
Fred Draked86ed291999-12-15 15:34:33 +00006396#ifdef _SC_INF
6397 {"SC_INF", _SC_INF},
6398#endif
Fred Drakec9680921999-12-13 16:37:25 +00006399#ifdef _SC_INT_MAX
6400 {"SC_INT_MAX", _SC_INT_MAX},
6401#endif
6402#ifdef _SC_INT_MIN
6403 {"SC_INT_MIN", _SC_INT_MIN},
6404#endif
6405#ifdef _SC_IOV_MAX
6406 {"SC_IOV_MAX", _SC_IOV_MAX},
6407#endif
Fred Draked86ed291999-12-15 15:34:33 +00006408#ifdef _SC_IP_SECOPTS
6409 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6410#endif
Fred Drakec9680921999-12-13 16:37:25 +00006411#ifdef _SC_JOB_CONTROL
6412 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6413#endif
Fred Draked86ed291999-12-15 15:34:33 +00006414#ifdef _SC_KERN_POINTERS
6415 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6416#endif
6417#ifdef _SC_KERN_SIM
6418 {"SC_KERN_SIM", _SC_KERN_SIM},
6419#endif
Fred Drakec9680921999-12-13 16:37:25 +00006420#ifdef _SC_LINE_MAX
6421 {"SC_LINE_MAX", _SC_LINE_MAX},
6422#endif
6423#ifdef _SC_LOGIN_NAME_MAX
6424 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6425#endif
6426#ifdef _SC_LOGNAME_MAX
6427 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6428#endif
6429#ifdef _SC_LONG_BIT
6430 {"SC_LONG_BIT", _SC_LONG_BIT},
6431#endif
Fred Draked86ed291999-12-15 15:34:33 +00006432#ifdef _SC_MAC
6433 {"SC_MAC", _SC_MAC},
6434#endif
Fred Drakec9680921999-12-13 16:37:25 +00006435#ifdef _SC_MAPPED_FILES
6436 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6437#endif
6438#ifdef _SC_MAXPID
6439 {"SC_MAXPID", _SC_MAXPID},
6440#endif
6441#ifdef _SC_MB_LEN_MAX
6442 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6443#endif
6444#ifdef _SC_MEMLOCK
6445 {"SC_MEMLOCK", _SC_MEMLOCK},
6446#endif
6447#ifdef _SC_MEMLOCK_RANGE
6448 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6449#endif
6450#ifdef _SC_MEMORY_PROTECTION
6451 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6452#endif
6453#ifdef _SC_MESSAGE_PASSING
6454 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6455#endif
Fred Draked86ed291999-12-15 15:34:33 +00006456#ifdef _SC_MMAP_FIXED_ALIGNMENT
6457 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6458#endif
Fred Drakec9680921999-12-13 16:37:25 +00006459#ifdef _SC_MQ_OPEN_MAX
6460 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6461#endif
6462#ifdef _SC_MQ_PRIO_MAX
6463 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6464#endif
Fred Draked86ed291999-12-15 15:34:33 +00006465#ifdef _SC_NACLS_MAX
6466 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6467#endif
Fred Drakec9680921999-12-13 16:37:25 +00006468#ifdef _SC_NGROUPS_MAX
6469 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6470#endif
6471#ifdef _SC_NL_ARGMAX
6472 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6473#endif
6474#ifdef _SC_NL_LANGMAX
6475 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6476#endif
6477#ifdef _SC_NL_MSGMAX
6478 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6479#endif
6480#ifdef _SC_NL_NMAX
6481 {"SC_NL_NMAX", _SC_NL_NMAX},
6482#endif
6483#ifdef _SC_NL_SETMAX
6484 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6485#endif
6486#ifdef _SC_NL_TEXTMAX
6487 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6488#endif
6489#ifdef _SC_NPROCESSORS_CONF
6490 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6491#endif
6492#ifdef _SC_NPROCESSORS_ONLN
6493 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6494#endif
Fred Draked86ed291999-12-15 15:34:33 +00006495#ifdef _SC_NPROC_CONF
6496 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6497#endif
6498#ifdef _SC_NPROC_ONLN
6499 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6500#endif
Fred Drakec9680921999-12-13 16:37:25 +00006501#ifdef _SC_NZERO
6502 {"SC_NZERO", _SC_NZERO},
6503#endif
6504#ifdef _SC_OPEN_MAX
6505 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6506#endif
6507#ifdef _SC_PAGESIZE
6508 {"SC_PAGESIZE", _SC_PAGESIZE},
6509#endif
6510#ifdef _SC_PAGE_SIZE
6511 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6512#endif
6513#ifdef _SC_PASS_MAX
6514 {"SC_PASS_MAX", _SC_PASS_MAX},
6515#endif
6516#ifdef _SC_PHYS_PAGES
6517 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6518#endif
6519#ifdef _SC_PII
6520 {"SC_PII", _SC_PII},
6521#endif
6522#ifdef _SC_PII_INTERNET
6523 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6524#endif
6525#ifdef _SC_PII_INTERNET_DGRAM
6526 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6527#endif
6528#ifdef _SC_PII_INTERNET_STREAM
6529 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6530#endif
6531#ifdef _SC_PII_OSI
6532 {"SC_PII_OSI", _SC_PII_OSI},
6533#endif
6534#ifdef _SC_PII_OSI_CLTS
6535 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6536#endif
6537#ifdef _SC_PII_OSI_COTS
6538 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6539#endif
6540#ifdef _SC_PII_OSI_M
6541 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6542#endif
6543#ifdef _SC_PII_SOCKET
6544 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6545#endif
6546#ifdef _SC_PII_XTI
6547 {"SC_PII_XTI", _SC_PII_XTI},
6548#endif
6549#ifdef _SC_POLL
6550 {"SC_POLL", _SC_POLL},
6551#endif
6552#ifdef _SC_PRIORITIZED_IO
6553 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6554#endif
6555#ifdef _SC_PRIORITY_SCHEDULING
6556 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6557#endif
6558#ifdef _SC_REALTIME_SIGNALS
6559 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6560#endif
6561#ifdef _SC_RE_DUP_MAX
6562 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6563#endif
6564#ifdef _SC_RTSIG_MAX
6565 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6566#endif
6567#ifdef _SC_SAVED_IDS
6568 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6569#endif
6570#ifdef _SC_SCHAR_MAX
6571 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6572#endif
6573#ifdef _SC_SCHAR_MIN
6574 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6575#endif
6576#ifdef _SC_SELECT
6577 {"SC_SELECT", _SC_SELECT},
6578#endif
6579#ifdef _SC_SEMAPHORES
6580 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6581#endif
6582#ifdef _SC_SEM_NSEMS_MAX
6583 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6584#endif
6585#ifdef _SC_SEM_VALUE_MAX
6586 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6587#endif
6588#ifdef _SC_SHARED_MEMORY_OBJECTS
6589 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6590#endif
6591#ifdef _SC_SHRT_MAX
6592 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6593#endif
6594#ifdef _SC_SHRT_MIN
6595 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6596#endif
6597#ifdef _SC_SIGQUEUE_MAX
6598 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6599#endif
6600#ifdef _SC_SIGRT_MAX
6601 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6602#endif
6603#ifdef _SC_SIGRT_MIN
6604 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6605#endif
Fred Draked86ed291999-12-15 15:34:33 +00006606#ifdef _SC_SOFTPOWER
6607 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6608#endif
Fred Drakec9680921999-12-13 16:37:25 +00006609#ifdef _SC_SPLIT_CACHE
6610 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6611#endif
6612#ifdef _SC_SSIZE_MAX
6613 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6614#endif
6615#ifdef _SC_STACK_PROT
6616 {"SC_STACK_PROT", _SC_STACK_PROT},
6617#endif
6618#ifdef _SC_STREAM_MAX
6619 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6620#endif
6621#ifdef _SC_SYNCHRONIZED_IO
6622 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6623#endif
6624#ifdef _SC_THREADS
6625 {"SC_THREADS", _SC_THREADS},
6626#endif
6627#ifdef _SC_THREAD_ATTR_STACKADDR
6628 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6629#endif
6630#ifdef _SC_THREAD_ATTR_STACKSIZE
6631 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6632#endif
6633#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6634 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6635#endif
6636#ifdef _SC_THREAD_KEYS_MAX
6637 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6638#endif
6639#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6640 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6641#endif
6642#ifdef _SC_THREAD_PRIO_INHERIT
6643 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6644#endif
6645#ifdef _SC_THREAD_PRIO_PROTECT
6646 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6647#endif
6648#ifdef _SC_THREAD_PROCESS_SHARED
6649 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6650#endif
6651#ifdef _SC_THREAD_SAFE_FUNCTIONS
6652 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6653#endif
6654#ifdef _SC_THREAD_STACK_MIN
6655 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6656#endif
6657#ifdef _SC_THREAD_THREADS_MAX
6658 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6659#endif
6660#ifdef _SC_TIMERS
6661 {"SC_TIMERS", _SC_TIMERS},
6662#endif
6663#ifdef _SC_TIMER_MAX
6664 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6665#endif
6666#ifdef _SC_TTY_NAME_MAX
6667 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6668#endif
6669#ifdef _SC_TZNAME_MAX
6670 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6671#endif
6672#ifdef _SC_T_IOV_MAX
6673 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6674#endif
6675#ifdef _SC_UCHAR_MAX
6676 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6677#endif
6678#ifdef _SC_UINT_MAX
6679 {"SC_UINT_MAX", _SC_UINT_MAX},
6680#endif
6681#ifdef _SC_UIO_MAXIOV
6682 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6683#endif
6684#ifdef _SC_ULONG_MAX
6685 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6686#endif
6687#ifdef _SC_USHRT_MAX
6688 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6689#endif
6690#ifdef _SC_VERSION
6691 {"SC_VERSION", _SC_VERSION},
6692#endif
6693#ifdef _SC_WORD_BIT
6694 {"SC_WORD_BIT", _SC_WORD_BIT},
6695#endif
6696#ifdef _SC_XBS5_ILP32_OFF32
6697 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6698#endif
6699#ifdef _SC_XBS5_ILP32_OFFBIG
6700 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6701#endif
6702#ifdef _SC_XBS5_LP64_OFF64
6703 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6704#endif
6705#ifdef _SC_XBS5_LPBIG_OFFBIG
6706 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6707#endif
6708#ifdef _SC_XOPEN_CRYPT
6709 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6710#endif
6711#ifdef _SC_XOPEN_ENH_I18N
6712 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6713#endif
6714#ifdef _SC_XOPEN_LEGACY
6715 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6716#endif
6717#ifdef _SC_XOPEN_REALTIME
6718 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6719#endif
6720#ifdef _SC_XOPEN_REALTIME_THREADS
6721 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6722#endif
6723#ifdef _SC_XOPEN_SHM
6724 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6725#endif
6726#ifdef _SC_XOPEN_UNIX
6727 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6728#endif
6729#ifdef _SC_XOPEN_VERSION
6730 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6731#endif
6732#ifdef _SC_XOPEN_XCU_VERSION
6733 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6734#endif
6735#ifdef _SC_XOPEN_XPG2
6736 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6737#endif
6738#ifdef _SC_XOPEN_XPG3
6739 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6740#endif
6741#ifdef _SC_XOPEN_XPG4
6742 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6743#endif
6744};
6745
6746static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006747conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006748{
6749 return conv_confname(arg, valuep, posix_constants_sysconf,
6750 sizeof(posix_constants_sysconf)
6751 / sizeof(struct constdef));
6752}
6753
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006754PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006755"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006756Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006757
6758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006759posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006760{
6761 PyObject *result = NULL;
6762 int name;
6763
6764 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6765 int value;
6766
6767 errno = 0;
6768 value = sysconf(name);
6769 if (value == -1 && errno != 0)
6770 posix_error();
6771 else
6772 result = PyInt_FromLong(value);
6773 }
6774 return result;
6775}
6776#endif
6777
6778
Fred Drakebec628d1999-12-15 18:31:10 +00006779/* This code is used to ensure that the tables of configuration value names
6780 * are in sorted order as required by conv_confname(), and also to build the
6781 * the exported dictionaries that are used to publish information about the
6782 * names available on the host platform.
6783 *
6784 * Sorting the table at runtime ensures that the table is properly ordered
6785 * when used, even for platforms we're not able to test on. It also makes
6786 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006787 */
Fred Drakebec628d1999-12-15 18:31:10 +00006788
6789static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006790cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006791{
6792 const struct constdef *c1 =
6793 (const struct constdef *) v1;
6794 const struct constdef *c2 =
6795 (const struct constdef *) v2;
6796
6797 return strcmp(c1->name, c2->name);
6798}
6799
6800static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006801setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006802 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006803{
Fred Drakebec628d1999-12-15 18:31:10 +00006804 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006805 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006806
6807 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6808 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006809 if (d == NULL)
6810 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006811
Barry Warsaw3155db32000-04-13 15:20:40 +00006812 for (i=0; i < tablesize; ++i) {
6813 PyObject *o = PyInt_FromLong(table[i].value);
6814 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6815 Py_XDECREF(o);
6816 Py_DECREF(d);
6817 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006818 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006819 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006820 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006821 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006822}
6823
Fred Drakebec628d1999-12-15 18:31:10 +00006824/* Return -1 on failure, 0 on success. */
6825static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006826setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006827{
6828#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006829 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006830 sizeof(posix_constants_pathconf)
6831 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006832 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006833 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006834#endif
6835#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006836 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006837 sizeof(posix_constants_confstr)
6838 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006839 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006840 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006841#endif
6842#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006843 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006844 sizeof(posix_constants_sysconf)
6845 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006846 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006847 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006848#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006849 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006850}
Fred Draked86ed291999-12-15 15:34:33 +00006851
6852
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006853PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006854"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006855Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006856in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006857
6858static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006859posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006860{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006861 abort();
6862 /*NOTREACHED*/
6863 Py_FatalError("abort() called from Python code didn't abort!");
6864 return NULL;
6865}
Fred Drakebec628d1999-12-15 18:31:10 +00006866
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006867#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006868PyDoc_STRVAR(win32_startfile__doc__,
6869"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006870\n\
6871This acts like double-clicking the file in Explorer, or giving the file\n\
6872name as an argument to the DOS \"start\" command: the file is opened\n\
6873with whatever application (if any) its extension is associated.\n\
6874\n\
6875startfile returns as soon as the associated application is launched.\n\
6876There is no option to wait for the application to close, and no way\n\
6877to retrieve the application's exit status.\n\
6878\n\
6879The filepath is relative to the current directory. If you want to use\n\
6880an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006881the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006882
6883static PyObject *
6884win32_startfile(PyObject *self, PyObject *args)
6885{
6886 char *filepath;
6887 HINSTANCE rc;
6888 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6889 return NULL;
6890 Py_BEGIN_ALLOW_THREADS
6891 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6892 Py_END_ALLOW_THREADS
6893 if (rc <= (HINSTANCE)32)
6894 return win32_error("startfile", filepath);
6895 Py_INCREF(Py_None);
6896 return Py_None;
6897}
6898#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006899
Martin v. Löwis438b5342002-12-27 10:16:42 +00006900#ifdef HAVE_GETLOADAVG
6901PyDoc_STRVAR(posix_getloadavg__doc__,
6902"getloadavg() -> (float, float, float)\n\n\
6903Return the number of processes in the system run queue averaged over\n\
6904the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6905was unobtainable");
6906
6907static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006908posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006909{
6910 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006911 if (getloadavg(loadavg, 3)!=3) {
6912 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6913 return NULL;
6914 } else
6915 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6916}
6917#endif
6918
6919
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006920static PyMethodDef posix_methods[] = {
6921 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6922#ifdef HAVE_TTYNAME
6923 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6924#endif
6925 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6926 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006927#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006928 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006929#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006930#ifdef HAVE_LCHOWN
6931 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6932#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006933#ifdef HAVE_CHROOT
6934 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6935#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006936#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006937 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006938#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006939#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006940 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00006941#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00006942 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006943#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00006944#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006945#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006946 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006947#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006948 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6949 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6950 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006951#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006952 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006953#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006954#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006955 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006956#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006957 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6958 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6959 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006960 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006961#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006962 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006963#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006964#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006965 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006966#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006967 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006968#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006969 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006970#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006971 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6972 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6973 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006974#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006975 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006976#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006977 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006978#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006979 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6980 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006981#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006982#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006983 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6984 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006985#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006986#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006987 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006988#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006989#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006990 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006991#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006992#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006993 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006994#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006995#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006996 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006997#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006998#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006999 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007000#endif /* HAVE_GETEGID */
7001#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007002 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007003#endif /* HAVE_GETEUID */
7004#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007005 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007006#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007007#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007008 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007009#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007010 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007011#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007012 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007013#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007014#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007015 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007016#endif /* HAVE_GETPPID */
7017#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007018 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007019#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007020#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007021 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007022#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007023#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007024 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007025#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007026#ifdef HAVE_KILLPG
7027 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7028#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007029#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007030 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007031#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007032#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007033 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007034#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007035 {"popen2", win32_popen2, METH_VARARGS},
7036 {"popen3", win32_popen3, METH_VARARGS},
7037 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007038 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007039#else
7040#if defined(PYOS_OS2) && defined(PYCC_GCC)
7041 {"popen2", os2emx_popen2, METH_VARARGS},
7042 {"popen3", os2emx_popen3, METH_VARARGS},
7043 {"popen4", os2emx_popen4, METH_VARARGS},
7044#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007045#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007046#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007047#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007048 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007049#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007050#ifdef HAVE_SETEUID
7051 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7052#endif /* HAVE_SETEUID */
7053#ifdef HAVE_SETEGID
7054 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7055#endif /* HAVE_SETEGID */
7056#ifdef HAVE_SETREUID
7057 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7058#endif /* HAVE_SETREUID */
7059#ifdef HAVE_SETREGID
7060 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7061#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007062#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007063 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007064#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007065#ifdef HAVE_SETGROUPS
7066 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7067#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007068#ifdef HAVE_GETPGID
7069 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7070#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007071#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007072 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007073#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007074#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007075 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007076#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007077#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007078 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007079#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007080#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007081 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007082#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007083#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007084 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007085#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007086#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007087 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007088#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007089#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007090 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007091#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007092 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7093 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7094 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7095 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7096 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7097 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7098 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7099 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7100 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007101 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007102#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007103 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007104#endif
7105#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007106 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007107#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007108#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007109 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7110#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007111#ifdef HAVE_DEVICE_MACROS
7112 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7113 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7114 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7115#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007116#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007117 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007118#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007119#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007120 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007121#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007122#ifdef HAVE_UNSETENV
7123 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7124#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007125#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007126 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007127#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007128#ifdef HAVE_FCHDIR
7129 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7130#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007131#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007132 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007133#endif
7134#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007135 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007136#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007137#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007138#ifdef WCOREDUMP
7139 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7140#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007141#ifdef WIFCONTINUED
7142 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7143#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007144#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007145 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007146#endif /* WIFSTOPPED */
7147#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007148 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007149#endif /* WIFSIGNALED */
7150#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007151 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007152#endif /* WIFEXITED */
7153#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007154 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007155#endif /* WEXITSTATUS */
7156#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007157 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007158#endif /* WTERMSIG */
7159#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007160 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007161#endif /* WSTOPSIG */
7162#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007163#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007164 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007165#endif
7166#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007167 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007168#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007169#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007170 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007171#endif
7172#ifdef HAVE_TEMPNAM
7173 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7174#endif
7175#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007176 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007177#endif
Fred Drakec9680921999-12-13 16:37:25 +00007178#ifdef HAVE_CONFSTR
7179 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7180#endif
7181#ifdef HAVE_SYSCONF
7182 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7183#endif
7184#ifdef HAVE_FPATHCONF
7185 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7186#endif
7187#ifdef HAVE_PATHCONF
7188 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7189#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007190 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007191#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007192 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7193#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007194#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007195 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007196#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007197 {NULL, NULL} /* Sentinel */
7198};
7199
7200
Barry Warsaw4a342091996-12-19 23:50:02 +00007201static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007202ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007203{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007204 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007205}
7206
Guido van Rossumd48f2521997-12-05 22:19:34 +00007207#if defined(PYOS_OS2)
7208/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007209static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007210{
7211 APIRET rc;
7212 ULONG values[QSV_MAX+1];
7213 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007214 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007215
7216 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007217 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007218 Py_END_ALLOW_THREADS
7219
7220 if (rc != NO_ERROR) {
7221 os2_error(rc);
7222 return -1;
7223 }
7224
Fred Drake4d1e64b2002-04-15 19:40:07 +00007225 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7226 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7227 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7228 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7229 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7230 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7231 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007232
7233 switch (values[QSV_VERSION_MINOR]) {
7234 case 0: ver = "2.00"; break;
7235 case 10: ver = "2.10"; break;
7236 case 11: ver = "2.11"; break;
7237 case 30: ver = "3.00"; break;
7238 case 40: ver = "4.00"; break;
7239 case 50: ver = "5.00"; break;
7240 default:
Tim Peters885d4572001-11-28 20:27:42 +00007241 PyOS_snprintf(tmp, sizeof(tmp),
7242 "%d-%d", values[QSV_VERSION_MAJOR],
7243 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007244 ver = &tmp[0];
7245 }
7246
7247 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007248 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007249 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007250
7251 /* Add Indicator of Which Drive was Used to Boot the System */
7252 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7253 tmp[1] = ':';
7254 tmp[2] = '\0';
7255
Fred Drake4d1e64b2002-04-15 19:40:07 +00007256 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007257}
7258#endif
7259
Barry Warsaw4a342091996-12-19 23:50:02 +00007260static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007261all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007262{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007263#ifdef F_OK
7264 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007265#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007266#ifdef R_OK
7267 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007268#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007269#ifdef W_OK
7270 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007271#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007272#ifdef X_OK
7273 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007274#endif
Fred Drakec9680921999-12-13 16:37:25 +00007275#ifdef NGROUPS_MAX
7276 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7277#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007278#ifdef TMP_MAX
7279 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7280#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007281#ifdef WCONTINUED
7282 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7283#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007284#ifdef WNOHANG
7285 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007286#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007287#ifdef WUNTRACED
7288 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7289#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007290#ifdef O_RDONLY
7291 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7292#endif
7293#ifdef O_WRONLY
7294 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7295#endif
7296#ifdef O_RDWR
7297 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7298#endif
7299#ifdef O_NDELAY
7300 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7301#endif
7302#ifdef O_NONBLOCK
7303 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7304#endif
7305#ifdef O_APPEND
7306 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7307#endif
7308#ifdef O_DSYNC
7309 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7310#endif
7311#ifdef O_RSYNC
7312 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7313#endif
7314#ifdef O_SYNC
7315 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7316#endif
7317#ifdef O_NOCTTY
7318 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7319#endif
7320#ifdef O_CREAT
7321 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7322#endif
7323#ifdef O_EXCL
7324 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7325#endif
7326#ifdef O_TRUNC
7327 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7328#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007329#ifdef O_BINARY
7330 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7331#endif
7332#ifdef O_TEXT
7333 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7334#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007335#ifdef O_LARGEFILE
7336 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7337#endif
7338
Tim Peters5aa91602002-01-30 05:46:57 +00007339/* MS Windows */
7340#ifdef O_NOINHERIT
7341 /* Don't inherit in child processes. */
7342 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7343#endif
7344#ifdef _O_SHORT_LIVED
7345 /* Optimize for short life (keep in memory). */
7346 /* MS forgot to define this one with a non-underscore form too. */
7347 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7348#endif
7349#ifdef O_TEMPORARY
7350 /* Automatically delete when last handle is closed. */
7351 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7352#endif
7353#ifdef O_RANDOM
7354 /* Optimize for random access. */
7355 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7356#endif
7357#ifdef O_SEQUENTIAL
7358 /* Optimize for sequential access. */
7359 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7360#endif
7361
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007362/* GNU extensions. */
7363#ifdef O_DIRECT
7364 /* Direct disk access. */
7365 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7366#endif
7367#ifdef O_DIRECTORY
7368 /* Must be a directory. */
7369 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7370#endif
7371#ifdef O_NOFOLLOW
7372 /* Do not follow links. */
7373 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7374#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007375
Barry Warsaw5676bd12003-01-07 20:57:09 +00007376 /* These come from sysexits.h */
7377#ifdef EX_OK
7378 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007379#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007380#ifdef EX_USAGE
7381 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007382#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007383#ifdef EX_DATAERR
7384 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007385#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007386#ifdef EX_NOINPUT
7387 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007388#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007389#ifdef EX_NOUSER
7390 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007391#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007392#ifdef EX_NOHOST
7393 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007394#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007395#ifdef EX_UNAVAILABLE
7396 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007397#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007398#ifdef EX_SOFTWARE
7399 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007400#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007401#ifdef EX_OSERR
7402 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007403#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007404#ifdef EX_OSFILE
7405 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007406#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007407#ifdef EX_CANTCREAT
7408 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007409#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007410#ifdef EX_IOERR
7411 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007412#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007413#ifdef EX_TEMPFAIL
7414 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007415#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007416#ifdef EX_PROTOCOL
7417 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007418#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007419#ifdef EX_NOPERM
7420 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007421#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007422#ifdef EX_CONFIG
7423 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007424#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007425#ifdef EX_NOTFOUND
7426 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007427#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007428
Guido van Rossum246bc171999-02-01 23:54:31 +00007429#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007430#if defined(PYOS_OS2) && defined(PYCC_GCC)
7431 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7432 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7433 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7434 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7435 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7436 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7437 if (ins(d, "P_PM", (long)P_PM)) return -1;
7438 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7439 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7440 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7441 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7442 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7443 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7444 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7445 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7446 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7447 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7448 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7449 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7450 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7451#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007452 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7453 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7454 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7455 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7456 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007457#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007458#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007459
Guido van Rossumd48f2521997-12-05 22:19:34 +00007460#if defined(PYOS_OS2)
7461 if (insertvalues(d)) return -1;
7462#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007463 return 0;
7464}
7465
7466
Tim Peters5aa91602002-01-30 05:46:57 +00007467#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007468#define INITFUNC initnt
7469#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007470
7471#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007472#define INITFUNC initos2
7473#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007474
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007475#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007476#define INITFUNC initposix
7477#define MODNAME "posix"
7478#endif
7479
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007480PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007481INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007482{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007483 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007484
Fred Drake4d1e64b2002-04-15 19:40:07 +00007485 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007486 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007487 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007488
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007489 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007490 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007491 Py_XINCREF(v);
7492 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007493 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007494 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007495
Fred Drake4d1e64b2002-04-15 19:40:07 +00007496 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007497 return;
7498
Fred Drake4d1e64b2002-04-15 19:40:07 +00007499 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007500 return;
7501
Fred Drake4d1e64b2002-04-15 19:40:07 +00007502 Py_INCREF(PyExc_OSError);
7503 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007504
Guido van Rossumb3d39562000-01-31 18:41:26 +00007505#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007506 if (posix_putenv_garbage == NULL)
7507 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007508#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007509
Guido van Rossum14648392001-12-08 18:02:58 +00007510 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007511 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7512 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7513 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007514 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007515 structseq_new = StatResultType.tp_new;
7516 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007517 Py_INCREF((PyObject*) &StatResultType);
7518 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007519
Guido van Rossum14648392001-12-08 18:02:58 +00007520 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007521 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007522 Py_INCREF((PyObject*) &StatVFSResultType);
7523 PyModule_AddObject(m, "statvfs_result",
7524 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007525}