blob: 87d584ec27995e4a3816ed3d76a74602cf1c4073 [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004/* This file is also used for Windows NT and MS-Win. In that case the module
Guido van Rossumad0ee831995-03-01 10:34:45 +00005 actually calls itself 'nt', not 'posix', and a few functions are
6 either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +00007 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000013static char posix__doc__ [] =
14"This module provides access to operating system functionality that is\n\
15standardized by the C Standard and the POSIX standard (a thinly\n\
16disguised Unix interface). Refer to the library manual and\n\
17corresponding Unix manual entries for more information on calls.";
18
Barry Warsaw53699e91996-12-10 23:23:01 +000019#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000020
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000021#if defined(PYOS_OS2)
22#define INCL_DOS
23#define INCL_DOSERRORS
24#define INCL_DOSPROCESS
25#define INCL_NOPMAPI
26#include <os2.h>
27#endif
28
Guido van Rossumb6775db1994-08-01 11:34:53 +000029#include <sys/types.h>
30#include <sys/stat.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +000031#ifdef HAVE_SYS_WAIT_H
32#include <sys/wait.h> /* For WNOHANG */
33#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000034
Guido van Rossuma376cc51996-12-05 23:43:35 +000035#ifdef HAVE_SIGNAL_H
36#include <signal.h>
37#endif
38
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#ifdef HAVE_FCNTL_H
40#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000041#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000042
Skip Montanaro8216c182001-02-27 17:04:34 +000043/* pick up declaration of confstr on some systems? */
44#ifdef HAVE_UNISTD_H
45#include <unistd.h>
46#endif /* HAVE_UNISTD_H */
47
Guido van Rossuma4916fa1996-05-23 22:58:55 +000048/* Various compilers have only certain posix functions */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000049/* XXX Gosh I wish these were all moved into config.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000050#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#include <process.h>
52#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000053#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000054#define HAVE_GETCWD 1
55#define HAVE_OPENDIR 1
56#define HAVE_SYSTEM 1
57#if defined(__OS2__)
58#define HAVE_EXECV 1
59#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000060#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000061#include <process.h>
62#else
63#ifdef __BORLANDC__ /* Borland compiler */
64#define HAVE_EXECV 1
65#define HAVE_GETCWD 1
66#define HAVE_GETEGID 1
67#define HAVE_GETEUID 1
68#define HAVE_GETGID 1
69#define HAVE_GETPPID 1
70#define HAVE_GETUID 1
71#define HAVE_KILL 1
72#define HAVE_OPENDIR 1
73#define HAVE_PIPE 1
74#define HAVE_POPEN 1
75#define HAVE_SYSTEM 1
76#define HAVE_WAIT 1
77#else
78#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000079#define HAVE_GETCWD 1
80#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000081#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#define HAVE_EXECV 1
83#define HAVE_PIPE 1
84#define HAVE_POPEN 1
85#define HAVE_SYSTEM 1
86#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000087#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#else /* all other compilers */
89/* Unix functions that the configure script doesn't check for */
90#define HAVE_EXECV 1
91#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000092#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
93#define HAVE_FORK1 1
94#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000095#define HAVE_GETCWD 1
96#define HAVE_GETEGID 1
97#define HAVE_GETEUID 1
98#define HAVE_GETGID 1
99#define HAVE_GETPPID 1
100#define HAVE_GETUID 1
101#define HAVE_KILL 1
102#define HAVE_OPENDIR 1
103#define HAVE_PIPE 1
104#define HAVE_POPEN 1
105#define HAVE_SYSTEM 1
106#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000107#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#endif /* _MSC_VER */
109#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000110#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000111#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000112
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000114
Guido van Rossumb6775db1994-08-01 11:34:53 +0000115#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000116#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000117#endif
118
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000119#if defined(sun) && !defined(__SVR4)
120/* SunOS 4.1.4 doesn't have prototypes for these: */
121extern int rename(const char *, const char *);
122extern int pclose(FILE *);
123extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000124extern int fsync(int);
125extern int lstat(const char *, struct stat *);
126extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000127#endif
128
Guido van Rossum36bc6801995-06-14 22:54:23 +0000129#ifdef NeXT
130/* NeXT's <unistd.h> and <utime.h> aren't worth much */
131#undef HAVE_UNISTD_H
132#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000133#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000134/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000135#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000136#endif
137
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000138#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int chmod(const char *, mode_t);
156extern int chown(const char *, uid_t, gid_t);
157extern char *getcwd(char *, int);
158extern char *strerror(int);
159extern int link(const char *, const char *);
160extern int rename(const char *, const char *);
161extern int stat(const char *, struct stat *);
162extern int unlink(const char *);
163extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000164#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000166#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000167#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000168extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000169#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000170#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000171
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#ifdef HAVE_UTIME_H
175#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000176#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000178#ifdef HAVE_SYS_UTIME_H
179#include <sys/utime.h>
180#define HAVE_UTIME_H /* pretend we do for the rest of this file */
181#endif /* HAVE_SYS_UTIME_H */
182
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#ifdef HAVE_SYS_TIMES_H
184#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000185#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186
187#ifdef HAVE_SYS_PARAM_H
188#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_UTSNAME_H
192#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifndef MAXPATHLEN
196#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#define NAMLEN(dirent) strlen((dirent)->d_name)
202#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#include <direct.h>
205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000218#endif
219#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <direct.h>
223#include <io.h>
224#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000225#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000227#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000229#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000230#else /* 16-bit Windows */
231#include <dos.h>
232#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000233#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
Mark Hammondef8b6542001-05-13 08:04:26 +0000236/* The default encoding used by the platform file system APIs
237 If non-NULL, this is almost certainly different than the default
238 encoding for strings (otherwise it can remain NULL!)
239*/
240#ifdef MS_WIN32
241const char *Py_FileSystemDefaultEncoding = "mbcs";
242#else
243const char *Py_FileSystemDefaultEncoding = NULL; /* use default */
244#endif
245
Guido van Rossumd48f2521997-12-05 22:19:34 +0000246#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000248#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000250#ifdef UNION_WAIT
251/* Emulate some macros on systems that have a union instead of macros */
252
253#ifndef WIFEXITED
254#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
255#endif
256
257#ifndef WEXITSTATUS
258#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
259#endif
260
261#ifndef WTERMSIG
262#define WTERMSIG(u_wait) ((u_wait).w_termsig)
263#endif
264
265#endif /* UNION_WAIT */
266
Greg Wardb48bc172000-03-01 21:51:56 +0000267/* Don't use the "_r" form if we don't need it (also, won't have a
268 prototype for it, at least on Solaris -- maybe others as well?). */
269#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
270#define USE_CTERMID_R
271#endif
272
273#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
274#define USE_TMPNAM_R
275#endif
276
Fred Drake699f3522000-06-29 21:12:41 +0000277/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000278#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000279#ifdef MS_WIN64
280# define STAT _stati64
281# define FSTAT _fstati64
282# define STRUCT_STAT struct _stati64
283#else
284# define STAT stat
285# define FSTAT fstat
286# define STRUCT_STAT struct stat
287#endif
288
289
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290/* Return a dictionary corresponding to the POSIX environment table */
291
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000292#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000294#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295
Barry Warsaw53699e91996-12-10 23:23:01 +0000296static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000297convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298{
Barry Warsaw53699e91996-12-10 23:23:01 +0000299 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000301 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 if (d == NULL)
303 return NULL;
304 if (environ == NULL)
305 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000306 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000308 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000309 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 char *p = strchr(*e, '=');
311 if (p == NULL)
312 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000313 k = PyString_FromStringAndSize(*e, (int)(p-*e));
314 if (k == NULL) {
315 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000317 }
318 v = PyString_FromString(p+1);
319 if (v == NULL) {
320 PyErr_Clear();
321 Py_DECREF(k);
322 continue;
323 }
324 if (PyDict_GetItem(d, k) == NULL) {
325 if (PyDict_SetItem(d, k, v) != 0)
326 PyErr_Clear();
327 }
328 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000329 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000331#if defined(PYOS_OS2)
332 {
333 APIRET rc;
334 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
335
336 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000337 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000338 PyObject *v = PyString_FromString(buffer);
339 PyDict_SetItemString(d, "BEGINLIBPATH", v);
340 Py_DECREF(v);
341 }
342 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
343 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
344 PyObject *v = PyString_FromString(buffer);
345 PyDict_SetItemString(d, "ENDLIBPATH", v);
346 Py_DECREF(v);
347 }
348 }
349#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000350 return d;
351}
352
353
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354/* Set a POSIX-specific error from errno, and return NULL */
355
Barry Warsawd58d7641998-07-23 16:14:40 +0000356static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000357posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000358{
Barry Warsawca74da41999-02-09 19:31:45 +0000359 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000360}
Barry Warsawd58d7641998-07-23 16:14:40 +0000361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000362posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000363{
Barry Warsawca74da41999-02-09 19:31:45 +0000364 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000365}
366
Mark Hammondef8b6542001-05-13 08:04:26 +0000367static PyObject *
368posix_error_with_allocated_filename(char* name)
369{
370 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
371 PyMem_Free(name);
372 return rc;
373}
374
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000375#ifdef MS_WIN32
376static PyObject *
377win32_error(char* function, char* filename)
378{
Mark Hammond33a6da92000-08-15 00:46:38 +0000379 /* XXX We should pass the function name along in the future.
380 (_winreg.c also wants to pass the function name.)
381 This would however require an additional param to the
382 Windows error object, which is non-trivial.
383 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000384 errno = GetLastError();
385 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000386 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000387 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000388 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000389}
390#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000391
Guido van Rossumd48f2521997-12-05 22:19:34 +0000392#if defined(PYOS_OS2)
393/**********************************************************************
394 * Helper Function to Trim and Format OS/2 Messages
395 **********************************************************************/
396 static void
397os2_formatmsg(char *msgbuf, int msglen, char *reason)
398{
399 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
400
401 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
402 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
403
404 while (lastc > msgbuf && isspace(*lastc))
405 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
406 }
407
408 /* Add Optional Reason Text */
409 if (reason) {
410 strcat(msgbuf, " : ");
411 strcat(msgbuf, reason);
412 }
413}
414
415/**********************************************************************
416 * Decode an OS/2 Operating System Error Code
417 *
418 * A convenience function to lookup an OS/2 error code and return a
419 * text message we can use to raise a Python exception.
420 *
421 * Notes:
422 * The messages for errors returned from the OS/2 kernel reside in
423 * the file OSO001.MSG in the \OS2 directory hierarchy.
424 *
425 **********************************************************************/
426 static char *
427os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
428{
429 APIRET rc;
430 ULONG msglen;
431
432 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
433 Py_BEGIN_ALLOW_THREADS
434 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
435 errorcode, "oso001.msg", &msglen);
436 Py_END_ALLOW_THREADS
437
438 if (rc == NO_ERROR)
439 os2_formatmsg(msgbuf, msglen, reason);
440 else
441 sprintf(msgbuf, "unknown OS error #%d", errorcode);
442
443 return msgbuf;
444}
445
446/* Set an OS/2-specific error and return NULL. OS/2 kernel
447 errors are not in a global variable e.g. 'errno' nor are
448 they congruent with posix error numbers. */
449
450static PyObject * os2_error(int code)
451{
452 char text[1024];
453 PyObject *v;
454
455 os2_strerror(text, sizeof(text), code, "");
456
457 v = Py_BuildValue("(is)", code, text);
458 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000459 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000460 Py_DECREF(v);
461 }
462 return NULL; /* Signal to Python that an Exception is Pending */
463}
464
465#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000466
467/* POSIX generic methods */
468
Barry Warsaw53699e91996-12-10 23:23:01 +0000469static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000470posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000471{
472 int fd;
473 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000474 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000475 return NULL;
476 Py_BEGIN_ALLOW_THREADS
477 res = (*func)(fd);
478 Py_END_ALLOW_THREADS
479 if (res < 0)
480 return posix_error();
481 Py_INCREF(Py_None);
482 return Py_None;
483}
484
485
486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000487posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488{
Mark Hammondef8b6542001-05-13 08:04:26 +0000489 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000491 if (!PyArg_ParseTuple(args, format,
492 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000493 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000494 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000495 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000496 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000497 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000498 return posix_error_with_allocated_filename(path1);
499 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000500 Py_INCREF(Py_None);
501 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502}
503
Barry Warsaw53699e91996-12-10 23:23:01 +0000504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000505posix_2str(PyObject *args, char *format,
506 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000507{
Mark Hammondef8b6542001-05-13 08:04:26 +0000508 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000509 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000510 if (!PyArg_ParseTuple(args, format,
511 Py_FileSystemDefaultEncoding, &path1,
512 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000514 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000515 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000516 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000517 PyMem_Free(path1);
518 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000519 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000520 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000521 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000522 Py_INCREF(Py_None);
523 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000524}
525
Fred Drake699f3522000-06-29 21:12:41 +0000526/* pack a system stat C structure into the Python stat tuple
527 (used by posix_stat() and posix_fstat()) */
528static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000529_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000530{
531 PyObject *v = PyTuple_New(10);
532 if (v == NULL)
533 return NULL;
534
535 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
536#ifdef HAVE_LARGEFILE_SUPPORT
537 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
538#else
539 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
540#endif
541#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
542 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
543#else
544 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
545#endif
546 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
547 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
548 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
549#ifdef HAVE_LARGEFILE_SUPPORT
550 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
551#else
552 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
553#endif
554#if SIZEOF_TIME_T > SIZEOF_LONG
555 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
556 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
557 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
558#else
559 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
560 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
561 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
562#endif
563
564 if (PyErr_Occurred()) {
565 Py_DECREF(v);
566 return NULL;
567 }
568
569 return v;
570}
571
572
Barry Warsaw53699e91996-12-10 23:23:01 +0000573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000574posix_do_stat(PyObject *self, PyObject *args, char *format,
575 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000576{
Fred Drake699f3522000-06-29 21:12:41 +0000577 STRUCT_STAT st;
Mark Hammondef8b6542001-05-13 08:04:26 +0000578 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000579 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000580
581#ifdef MS_WIN32
582 int pathlen;
583 char pathcopy[MAX_PATH];
584#endif /* MS_WIN32 */
585
Mark Hammondef8b6542001-05-13 08:04:26 +0000586 if (!PyArg_ParseTuple(args, format,
587 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000588 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000589
590#ifdef MS_WIN32
591 pathlen = strlen(path);
592 /* the library call can blow up if the file name is too long! */
593 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000594 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000595 errno = ENAMETOOLONG;
596 return posix_error();
597 }
598
599 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000600 /* exception for specific or current drive root */
601 if (!((pathlen == 1) ||
602 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000603 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000604 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000605 {
606 strncpy(pathcopy, path, pathlen);
607 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
608 path = pathcopy;
609 }
610 }
611#endif /* MS_WIN32 */
612
Barry Warsaw53699e91996-12-10 23:23:01 +0000613 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000614 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000615 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000616 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000617 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000618
Mark Hammondef8b6542001-05-13 08:04:26 +0000619 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000620 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000621}
622
623
624/* POSIX methods */
625
Guido van Rossum94f6f721999-01-06 18:42:14 +0000626static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000627"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000628Test for access to a file.";
629
630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000631posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000632{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000633 char *path;
634 int mode;
635 int res;
636
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000637 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000638 return NULL;
639 Py_BEGIN_ALLOW_THREADS
640 res = access(path, mode);
641 Py_END_ALLOW_THREADS
642 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000643}
644
Guido van Rossumd371ff11999-01-25 16:12:23 +0000645#ifndef F_OK
646#define F_OK 0
647#endif
648#ifndef R_OK
649#define R_OK 4
650#endif
651#ifndef W_OK
652#define W_OK 2
653#endif
654#ifndef X_OK
655#define X_OK 1
656#endif
657
658#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000659static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000660"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000661Return the name of the terminal device connected to 'fd'.";
662
663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000664posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000665{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000666 int id;
667 char *ret;
668
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000669 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000670 return NULL;
671
Guido van Rossum94f6f721999-01-06 18:42:14 +0000672 ret = ttyname(id);
673 if (ret == NULL)
674 return(posix_error());
675 return(PyString_FromString(ret));
676}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000677#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000678
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000679#ifdef HAVE_CTERMID
680static char posix_ctermid__doc__[] =
681"ctermid() -> String\n\
682Return the name of the controlling terminal for this process.";
683
684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000685posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000686{
687 char *ret;
688 char buffer[L_ctermid];
689
690 if (!PyArg_ParseTuple(args, ":ctermid"))
691 return NULL;
692
Greg Wardb48bc172000-03-01 21:51:56 +0000693#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000694 ret = ctermid_r(buffer);
695#else
696 ret = ctermid(buffer);
697#endif
698 if (ret == NULL)
699 return(posix_error());
700 return(PyString_FromString(buffer));
701}
702#endif
703
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000704static char posix_chdir__doc__[] =
705"chdir(path) -> None\n\
706Change the current working directory to the specified path.";
707
Barry Warsaw53699e91996-12-10 23:23:01 +0000708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000709posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000710{
Mark Hammondef8b6542001-05-13 08:04:26 +0000711 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000712}
713
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000714
715static char posix_chmod__doc__[] =
716"chmod(path, mode) -> None\n\
717Change the access permissions of a file.";
718
Barry Warsaw53699e91996-12-10 23:23:01 +0000719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000720posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000721{
Mark Hammondef8b6542001-05-13 08:04:26 +0000722 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000723 int i;
724 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000725 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
726 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000727 return NULL;
728 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000729 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000730 Py_END_ALLOW_THREADS
731 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000732 return posix_error_with_allocated_filename(path);
733 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000734 Py_INCREF(Py_None);
735 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000736}
737
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000738
Guido van Rossum21142a01999-01-08 21:05:37 +0000739#ifdef HAVE_FSYNC
740static char posix_fsync__doc__[] =
741"fsync(fildes) -> None\n\
742force write of file with filedescriptor to disk.";
743
744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000745posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000746{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000747 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000748}
749#endif /* HAVE_FSYNC */
750
751#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000752
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000753#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000754extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
755#endif
756
Guido van Rossum21142a01999-01-08 21:05:37 +0000757static char posix_fdatasync__doc__[] =
758"fdatasync(fildes) -> None\n\
759force write of file with filedescriptor to disk.\n\
760 does not force update of metadata.";
761
762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000763posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000764{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000765 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000766}
767#endif /* HAVE_FDATASYNC */
768
769
Fredrik Lundh10723342000-07-10 16:38:09 +0000770#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000771static char posix_chown__doc__[] =
772"chown(path, uid, gid) -> None\n\
773Change the owner and group id of path to the numeric uid and gid.";
774
Barry Warsaw53699e91996-12-10 23:23:01 +0000775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000776posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000777{
Mark Hammondef8b6542001-05-13 08:04:26 +0000778 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000779 int uid, gid;
780 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000781 if (!PyArg_ParseTuple(args, "etii:chown",
782 Py_FileSystemDefaultEncoding, &path,
783 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000784 return NULL;
785 Py_BEGIN_ALLOW_THREADS
786 res = chown(path, (uid_t) uid, (gid_t) gid);
787 Py_END_ALLOW_THREADS
788 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000789 return posix_error_with_allocated_filename(path);
790 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000791 Py_INCREF(Py_None);
792 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000793}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000794#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000796
Guido van Rossum36bc6801995-06-14 22:54:23 +0000797#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000798static char posix_getcwd__doc__[] =
799"getcwd() -> path\n\
800Return a string representing the current working directory.";
801
Barry Warsaw53699e91996-12-10 23:23:01 +0000802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000803posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000804{
805 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000806 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000807 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000808 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000809 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000810 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000811 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000812 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000814 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000815}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000816#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000818
Guido van Rossumb6775db1994-08-01 11:34:53 +0000819#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000820static char posix_link__doc__[] =
821"link(src, dst) -> None\n\
822Create a hard link to a file.";
823
Barry Warsaw53699e91996-12-10 23:23:01 +0000824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000825posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000826{
Mark Hammondef8b6542001-05-13 08:04:26 +0000827 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000828}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000829#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000830
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000831
832static char posix_listdir__doc__[] =
833"listdir(path) -> list_of_strings\n\
834Return a list containing the names of the entries in the directory.\n\
835\n\
836 path: path of directory to list\n\
837\n\
838The list is in arbitrary order. It does not include the special\n\
839entries '.' and '..' even if they are present in the directory.";
840
Barry Warsaw53699e91996-12-10 23:23:01 +0000841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000842posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000843{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000844 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000845 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000846#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000847
Barry Warsaw53699e91996-12-10 23:23:01 +0000848 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000849 HANDLE hFindFile;
850 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000851 /* MAX_PATH characters could mean a bigger encoded string */
852 char namebuf[MAX_PATH*2+5];
853 char *bufptr = namebuf;
854 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000855 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000856
Mark Hammondef8b6542001-05-13 08:04:26 +0000857 if (!PyArg_ParseTuple(args, "et#:listdir",
858 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000859 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000860 ch = namebuf[len-1];
861 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000862 namebuf[len++] = '/';
863 strcpy(namebuf + len, "*.*");
864
Barry Warsaw53699e91996-12-10 23:23:01 +0000865 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000866 return NULL;
867
868 hFindFile = FindFirstFile(namebuf, &FileData);
869 if (hFindFile == INVALID_HANDLE_VALUE) {
870 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000871 if (errno == ERROR_FILE_NOT_FOUND)
872 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000873 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000874 }
875 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000876 if (FileData.cFileName[0] == '.' &&
877 (FileData.cFileName[1] == '\0' ||
878 FileData.cFileName[1] == '.' &&
879 FileData.cFileName[2] == '\0'))
880 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000881 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000882 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000883 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000884 d = NULL;
885 break;
886 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000887 if (PyList_Append(d, v) != 0) {
888 Py_DECREF(v);
889 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000890 d = NULL;
891 break;
892 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000893 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000894 } while (FindNextFile(hFindFile, &FileData) == TRUE);
895
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000896 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +0000897 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000898
899 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000900
Tim Peters0bb44a42000-09-15 07:44:49 +0000901#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000902
903#ifndef MAX_PATH
904#define MAX_PATH 250
905#endif
906 char *name, *pt;
907 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000908 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000909 char namebuf[MAX_PATH+5];
910 struct _find_t ep;
911
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000912 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000913 return NULL;
914 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000915 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000916 return NULL;
917 }
918 strcpy(namebuf, name);
919 for (pt = namebuf; *pt; pt++)
920 if (*pt == '/')
921 *pt = '\\';
922 if (namebuf[len-1] != '\\')
923 namebuf[len++] = '\\';
924 strcpy(namebuf + len, "*.*");
925
Barry Warsaw53699e91996-12-10 23:23:01 +0000926 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000927 return NULL;
928
929 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000930 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
931 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000932 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000933 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000934 }
935 do {
936 if (ep.name[0] == '.' &&
937 (ep.name[1] == '\0' ||
938 ep.name[1] == '.' &&
939 ep.name[2] == '\0'))
940 continue;
941 strcpy(namebuf, ep.name);
942 for (pt = namebuf; *pt; pt++)
943 if (isupper(*pt))
944 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000945 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000946 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000947 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000948 d = NULL;
949 break;
950 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000951 if (PyList_Append(d, v) != 0) {
952 Py_DECREF(v);
953 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000954 d = NULL;
955 break;
956 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000957 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000958 } while (_dos_findnext(&ep) == 0);
959
960 return d;
961
Tim Peters0bb44a42000-09-15 07:44:49 +0000962#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963
964#ifndef MAX_PATH
965#define MAX_PATH CCHMAXPATH
966#endif
967 char *name, *pt;
968 int len;
969 PyObject *d, *v;
970 char namebuf[MAX_PATH+5];
971 HDIR hdir = 1;
972 ULONG srchcnt = 1;
973 FILEFINDBUF3 ep;
974 APIRET rc;
975
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000976 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000977 return NULL;
978 if (len >= MAX_PATH) {
979 PyErr_SetString(PyExc_ValueError, "path too long");
980 return NULL;
981 }
982 strcpy(namebuf, name);
983 for (pt = namebuf; *pt; pt++)
984 if (*pt == '/')
985 *pt = '\\';
986 if (namebuf[len-1] != '\\')
987 namebuf[len++] = '\\';
988 strcpy(namebuf + len, "*.*");
989
990 if ((d = PyList_New(0)) == NULL)
991 return NULL;
992
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000993 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
994 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000995 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000996 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
997 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
998 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000999
1000 if (rc != NO_ERROR) {
1001 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001002 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001003 }
1004
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001005 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001006 do {
1007 if (ep.achName[0] == '.'
1008 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001009 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001010
1011 strcpy(namebuf, ep.achName);
1012
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001013 /* Leave Case of Name Alone -- In Native Form */
1014 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001015
1016 v = PyString_FromString(namebuf);
1017 if (v == NULL) {
1018 Py_DECREF(d);
1019 d = NULL;
1020 break;
1021 }
1022 if (PyList_Append(d, v) != 0) {
1023 Py_DECREF(v);
1024 Py_DECREF(d);
1025 d = NULL;
1026 break;
1027 }
1028 Py_DECREF(v);
1029 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1030 }
1031
1032 return d;
1033#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001034
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001035 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001036 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001037 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001038 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001039 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001040 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001041 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001042 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001043 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001044 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001045 closedir(dirp);
1046 return NULL;
1047 }
1048 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001049 if (ep->d_name[0] == '.' &&
1050 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001051 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001052 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001053 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001054 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001055 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001056 d = NULL;
1057 break;
1058 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001059 if (PyList_Append(d, v) != 0) {
1060 Py_DECREF(v);
1061 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001062 d = NULL;
1063 break;
1064 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001065 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001066 }
1067 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001068
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001069 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001070
Tim Peters0bb44a42000-09-15 07:44:49 +00001071#endif /* which OS */
1072} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001073
Mark Hammondef8b6542001-05-13 08:04:26 +00001074#ifdef MS_WIN32
1075/* A helper function for abspath on win32 */
1076static PyObject *
1077posix__getfullpathname(PyObject *self, PyObject *args)
1078{
1079 /* assume encoded strings wont more than double no of chars */
1080 char inbuf[MAX_PATH*2];
1081 char *inbufp = inbuf;
1082 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1083 char outbuf[MAX_PATH*2];
1084 char *temp;
1085 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1086 Py_FileSystemDefaultEncoding, &inbufp,
1087 &insize))
1088 return NULL;
1089 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1090 outbuf, &temp))
1091 return win32_error("GetFullPathName", inbuf);
1092 return PyString_FromString(outbuf);
1093} /* end of posix__getfullpathname */
1094#endif /* MS_WIN32 */
1095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001096static char posix_mkdir__doc__[] =
1097"mkdir(path [, mode=0777]) -> None\n\
1098Create a directory.";
1099
Barry Warsaw53699e91996-12-10 23:23:01 +00001100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001101posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001102{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001103 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001104 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001105 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001106 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1107 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001108 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001109 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001110#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001111 res = mkdir(path);
1112#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001113 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001114#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001115 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001116 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001117 return posix_error_with_allocated_filename(path);
1118 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001119 Py_INCREF(Py_None);
1120 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001121}
1122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001123
Guido van Rossumb6775db1994-08-01 11:34:53 +00001124#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001125static char posix_nice__doc__[] =
1126"nice(inc) -> new_priority\n\
1127Decrease the priority of process and return new priority.";
1128
Barry Warsaw53699e91996-12-10 23:23:01 +00001129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001130posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001131{
1132 int increment, value;
1133
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001134 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001135 return NULL;
1136 value = nice(increment);
1137 if (value == -1)
1138 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001139 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001140}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001141#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001142
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001143
1144static char posix_rename__doc__[] =
1145"rename(old, new) -> None\n\
1146Rename a file or directory.";
1147
Barry Warsaw53699e91996-12-10 23:23:01 +00001148static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001149posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150{
Mark Hammondef8b6542001-05-13 08:04:26 +00001151 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001152}
1153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001154
1155static char posix_rmdir__doc__[] =
1156"rmdir(path) -> None\n\
1157Remove a directory.";
1158
Barry Warsaw53699e91996-12-10 23:23:01 +00001159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001160posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001161{
Mark Hammondef8b6542001-05-13 08:04:26 +00001162 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001163}
1164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001165
1166static char posix_stat__doc__[] =
1167"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1168Perform a stat system call on the given path.";
1169
Barry Warsaw53699e91996-12-10 23:23:01 +00001170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001171posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001172{
Mark Hammondef8b6542001-05-13 08:04:26 +00001173 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001174}
1175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001176
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001177#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001178static char posix_system__doc__[] =
1179"system(command) -> exit_status\n\
1180Execute the command (a string) in a subshell.";
1181
Barry Warsaw53699e91996-12-10 23:23:01 +00001182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001183posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001185 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001186 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001187 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001188 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001189 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001190 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001191 Py_END_ALLOW_THREADS
1192 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001193}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001194#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001196
1197static char posix_umask__doc__[] =
1198"umask(new_mask) -> old_mask\n\
1199Set the current numeric umask and return the previous umask.";
1200
Barry Warsaw53699e91996-12-10 23:23:01 +00001201static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001202posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001203{
1204 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001205 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001206 return NULL;
1207 i = umask(i);
1208 if (i < 0)
1209 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001210 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211}
1212
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001213
1214static char posix_unlink__doc__[] =
1215"unlink(path) -> None\n\
1216Remove a file (same as remove(path)).";
1217
1218static char posix_remove__doc__[] =
1219"remove(path) -> None\n\
1220Remove a file (same as unlink(path)).";
1221
Barry Warsaw53699e91996-12-10 23:23:01 +00001222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001223posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001224{
Mark Hammondef8b6542001-05-13 08:04:26 +00001225 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226}
1227
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001228
Guido van Rossumb6775db1994-08-01 11:34:53 +00001229#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001230static char posix_uname__doc__[] =
1231"uname() -> (sysname, nodename, release, version, machine)\n\
1232Return a tuple identifying the current operating system.";
1233
Barry Warsaw53699e91996-12-10 23:23:01 +00001234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001235posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001236{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001237 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001238 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001239 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001240 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001241 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001242 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001243 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001244 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001245 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001246 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001247 u.sysname,
1248 u.nodename,
1249 u.release,
1250 u.version,
1251 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001252}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001253#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001254
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001255
1256static char posix_utime__doc__[] =
1257"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001258utime(path, None) -> None\n\
1259Set the access and modified time of the file to the given values. If the\n\
1260second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001261
Barry Warsaw53699e91996-12-10 23:23:01 +00001262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001263posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001264{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001265 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001266 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001267 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001268 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001269
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001270/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001271#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001272 struct utimbuf buf;
1273#define ATIME buf.actime
1274#define MTIME buf.modtime
1275#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001276#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001277 time_t buf[2];
1278#define ATIME buf[0]
1279#define MTIME buf[1]
1280#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001281#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001282
Barry Warsaw3cef8562000-05-01 16:17:24 +00001283 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001284 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001285 if (arg == Py_None) {
1286 /* optional time values not given */
1287 Py_BEGIN_ALLOW_THREADS
1288 res = utime(path, NULL);
1289 Py_END_ALLOW_THREADS
1290 }
1291 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1292 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001293 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001294 return NULL;
1295 }
1296 else {
1297 ATIME = atime;
1298 MTIME = mtime;
1299 Py_BEGIN_ALLOW_THREADS
1300 res = utime(path, UTIME_ARG);
1301 Py_END_ALLOW_THREADS
1302 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001303 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001304 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001305 Py_INCREF(Py_None);
1306 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001307#undef UTIME_ARG
1308#undef ATIME
1309#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310}
1311
Guido van Rossum85e3b011991-06-03 12:42:10 +00001312
Guido van Rossum3b066191991-06-04 19:40:25 +00001313/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001315static char posix__exit__doc__[] =
1316"_exit(status)\n\
1317Exit to the system with specified status, without normal exit processing.";
1318
Barry Warsaw53699e91996-12-10 23:23:01 +00001319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001320posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001321{
1322 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001323 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001324 return NULL;
1325 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001326 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001327}
1328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001329
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001330#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001331static char posix_execv__doc__[] =
1332"execv(path, args)\n\
1333Execute an executable path with arguments, replacing current process.\n\
1334\n\
1335 path: path of executable file\n\
1336 args: tuple or list of strings";
1337
Barry Warsaw53699e91996-12-10 23:23:01 +00001338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001339posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001340{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001341 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001342 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001343 char **argvlist;
1344 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001345 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001346
Guido van Rossum89b33251993-10-22 14:26:06 +00001347 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001348 argv is a list or tuple of strings. */
1349
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001350 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001351 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001352 if (PyList_Check(argv)) {
1353 argc = PyList_Size(argv);
1354 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001355 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001356 else if (PyTuple_Check(argv)) {
1357 argc = PyTuple_Size(argv);
1358 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001359 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001360 else {
Fred Drake661ea262000-10-24 19:57:45 +00001361 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001362 return NULL;
1363 }
1364
1365 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001366 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001367 return NULL;
1368 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001369
Barry Warsaw53699e91996-12-10 23:23:01 +00001370 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001371 if (argvlist == NULL)
1372 return NULL;
1373 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001374 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1375 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001376 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001377 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001378 return NULL;
1379
Guido van Rossum85e3b011991-06-03 12:42:10 +00001380 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001381 }
1382 argvlist[argc] = NULL;
1383
Guido van Rossumb6775db1994-08-01 11:34:53 +00001384#ifdef BAD_EXEC_PROTOTYPES
1385 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001386#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001387 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001388#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001389
Guido van Rossum85e3b011991-06-03 12:42:10 +00001390 /* If we get here it's definitely an error */
1391
Barry Warsaw53699e91996-12-10 23:23:01 +00001392 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001393 return posix_error();
1394}
1395
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001396
1397static char posix_execve__doc__[] =
1398"execve(path, args, env)\n\
1399Execute a path with arguments and environment, replacing current process.\n\
1400\n\
1401 path: path of executable file\n\
1402 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001403 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001404
Barry Warsaw53699e91996-12-10 23:23:01 +00001405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001406posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001407{
1408 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001409 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001410 char **argvlist;
1411 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001412 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001413 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001414 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001415
1416 /* execve has three arguments: (path, argv, env), where
1417 argv is a list or tuple of strings and env is a dictionary
1418 like posix.environ. */
1419
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001420 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001421 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001422 if (PyList_Check(argv)) {
1423 argc = PyList_Size(argv);
1424 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001425 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001426 else if (PyTuple_Check(argv)) {
1427 argc = PyTuple_Size(argv);
1428 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001429 }
1430 else {
Fred Drake661ea262000-10-24 19:57:45 +00001431 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001432 return NULL;
1433 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001434 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001435 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001436 return NULL;
1437 }
1438
Guido van Rossum50422b42000-04-26 20:34:28 +00001439 if (argc == 0) {
1440 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001441 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001442 return NULL;
1443 }
1444
Barry Warsaw53699e91996-12-10 23:23:01 +00001445 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001446 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001447 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001448 return NULL;
1449 }
1450 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001451 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001452 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001453 &argvlist[i]))
1454 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001455 goto fail_1;
1456 }
1457 }
1458 argvlist[argc] = NULL;
1459
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001460 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001461 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001462 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001463 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001464 goto fail_1;
1465 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001466 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001467 keys = PyMapping_Keys(env);
1468 vals = PyMapping_Values(env);
1469 if (!keys || !vals)
1470 goto fail_2;
1471
1472 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001473 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001474
1475 key = PyList_GetItem(keys, pos);
1476 val = PyList_GetItem(vals, pos);
1477 if (!key || !val)
1478 goto fail_2;
1479
Fred Drake661ea262000-10-24 19:57:45 +00001480 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1481 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001482 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001483 goto fail_2;
1484 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001485
1486#if defined(PYOS_OS2)
1487 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1488 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1489#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001490 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001491 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001492 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001493 goto fail_2;
1494 }
1495 sprintf(p, "%s=%s", k, v);
1496 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001497#if defined(PYOS_OS2)
1498 }
1499#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001500 }
1501 envlist[envc] = 0;
1502
Guido van Rossumb6775db1994-08-01 11:34:53 +00001503
1504#ifdef BAD_EXEC_PROTOTYPES
1505 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001506#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001507 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001508#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001509
1510 /* If we get here it's definitely an error */
1511
1512 (void) posix_error();
1513
1514 fail_2:
1515 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001516 PyMem_DEL(envlist[envc]);
1517 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001518 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001519 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001520 Py_XDECREF(vals);
1521 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001522 return NULL;
1523}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001524#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001525
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001526
Guido van Rossuma1065681999-01-25 23:20:23 +00001527#ifdef HAVE_SPAWNV
1528static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001529"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001530Execute an executable path with arguments, replacing current process.\n\
1531\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001532 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001533 path: path of executable file\n\
1534 args: tuple or list of strings";
1535
1536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001537posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001538{
1539 char *path;
1540 PyObject *argv;
1541 char **argvlist;
1542 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001543 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001544 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001545
1546 /* spawnv has three arguments: (mode, path, argv), where
1547 argv is a list or tuple of strings. */
1548
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001549 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001550 return NULL;
1551 if (PyList_Check(argv)) {
1552 argc = PyList_Size(argv);
1553 getitem = PyList_GetItem;
1554 }
1555 else if (PyTuple_Check(argv)) {
1556 argc = PyTuple_Size(argv);
1557 getitem = PyTuple_GetItem;
1558 }
1559 else {
Fred Drake661ea262000-10-24 19:57:45 +00001560 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001561 return NULL;
1562 }
1563
1564 argvlist = PyMem_NEW(char *, argc+1);
1565 if (argvlist == NULL)
1566 return NULL;
1567 for (i = 0; i < argc; i++) {
1568 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1569 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001570 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001571 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001572 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001573 }
1574 }
1575 argvlist[argc] = NULL;
1576
Guido van Rossum246bc171999-02-01 23:54:31 +00001577 if (mode == _OLD_P_OVERLAY)
1578 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001579 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001580
1581 PyMem_DEL(argvlist);
1582
Fred Drake699f3522000-06-29 21:12:41 +00001583 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001584 return posix_error();
1585 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001586#if SIZEOF_LONG == SIZEOF_VOID_P
1587 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001588#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001589 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001590#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001591}
1592
1593
1594static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001595"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001596Execute a path with arguments and environment, replacing current process.\n\
1597\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001598 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001599 path: path of executable file\n\
1600 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001601 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001602
1603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001604posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001605{
1606 char *path;
1607 PyObject *argv, *env;
1608 char **argvlist;
1609 char **envlist;
1610 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1611 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001612 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001613 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001614
1615 /* spawnve has four arguments: (mode, path, argv, env), where
1616 argv is a list or tuple of strings and env is a dictionary
1617 like posix.environ. */
1618
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001619 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001620 return NULL;
1621 if (PyList_Check(argv)) {
1622 argc = PyList_Size(argv);
1623 getitem = PyList_GetItem;
1624 }
1625 else if (PyTuple_Check(argv)) {
1626 argc = PyTuple_Size(argv);
1627 getitem = PyTuple_GetItem;
1628 }
1629 else {
Fred Drake661ea262000-10-24 19:57:45 +00001630 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001631 return NULL;
1632 }
1633 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001634 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001635 return NULL;
1636 }
1637
1638 argvlist = PyMem_NEW(char *, argc+1);
1639 if (argvlist == NULL) {
1640 PyErr_NoMemory();
1641 return NULL;
1642 }
1643 for (i = 0; i < argc; i++) {
1644 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001645 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001646 &argvlist[i]))
1647 {
1648 goto fail_1;
1649 }
1650 }
1651 argvlist[argc] = NULL;
1652
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001653 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001654 envlist = PyMem_NEW(char *, i + 1);
1655 if (envlist == NULL) {
1656 PyErr_NoMemory();
1657 goto fail_1;
1658 }
1659 envc = 0;
1660 keys = PyMapping_Keys(env);
1661 vals = PyMapping_Values(env);
1662 if (!keys || !vals)
1663 goto fail_2;
1664
1665 for (pos = 0; pos < i; pos++) {
1666 char *p, *k, *v;
1667
1668 key = PyList_GetItem(keys, pos);
1669 val = PyList_GetItem(vals, pos);
1670 if (!key || !val)
1671 goto fail_2;
1672
Fred Drake661ea262000-10-24 19:57:45 +00001673 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1674 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001675 {
1676 goto fail_2;
1677 }
1678 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1679 if (p == NULL) {
1680 PyErr_NoMemory();
1681 goto fail_2;
1682 }
1683 sprintf(p, "%s=%s", k, v);
1684 envlist[envc++] = p;
1685 }
1686 envlist[envc] = 0;
1687
Guido van Rossum246bc171999-02-01 23:54:31 +00001688 if (mode == _OLD_P_OVERLAY)
1689 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001690 spawnval = _spawnve(mode, path, argvlist, envlist);
1691 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001692 (void) posix_error();
1693 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001694#if SIZEOF_LONG == SIZEOF_VOID_P
1695 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001696#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001697 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001698#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001699
1700 fail_2:
1701 while (--envc >= 0)
1702 PyMem_DEL(envlist[envc]);
1703 PyMem_DEL(envlist);
1704 fail_1:
1705 PyMem_DEL(argvlist);
1706 Py_XDECREF(vals);
1707 Py_XDECREF(keys);
1708 return res;
1709}
1710#endif /* HAVE_SPAWNV */
1711
1712
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001713#ifdef HAVE_FORK1
1714static char posix_fork1__doc__[] =
1715"fork1() -> pid\n\
1716Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1717\n\
1718Return 0 to child process and PID of child to parent process.";
1719
1720static PyObject *
1721posix_fork1(self, args)
1722 PyObject *self;
1723 PyObject *args;
1724{
1725 int pid;
1726 if (!PyArg_ParseTuple(args, ":fork1"))
1727 return NULL;
1728 pid = fork1();
1729 if (pid == -1)
1730 return posix_error();
1731 PyOS_AfterFork();
1732 return PyInt_FromLong((long)pid);
1733}
1734#endif
1735
1736
Guido van Rossumad0ee831995-03-01 10:34:45 +00001737#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001738static char posix_fork__doc__[] =
1739"fork() -> pid\n\
1740Fork a child process.\n\
1741\n\
1742Return 0 to child process and PID of child to parent process.";
1743
Barry Warsaw53699e91996-12-10 23:23:01 +00001744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001745posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001746{
1747 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001748 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001749 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001750 pid = fork();
1751 if (pid == -1)
1752 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001753 if (pid == 0)
1754 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001755 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001756}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001757#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001758
Fred Drake8cef4cf2000-06-28 16:40:38 +00001759#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1760#ifdef HAVE_PTY_H
1761#include <pty.h>
1762#else
1763#ifdef HAVE_LIBUTIL_H
1764#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001765#endif /* HAVE_LIBUTIL_H */
1766#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001767#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001768
Thomas Wouters70c21a12000-07-14 14:28:33 +00001769#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001770static char posix_openpty__doc__[] =
1771"openpty() -> (master_fd, slave_fd)\n\
1772Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1773
1774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001775posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001776{
1777 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001778#ifndef HAVE_OPENPTY
1779 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001780#endif
1781
Fred Drake8cef4cf2000-06-28 16:40:38 +00001782 if (!PyArg_ParseTuple(args, ":openpty"))
1783 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001784
1785#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001786 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1787 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001788#else
1789 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1790 if (slave_name == NULL)
1791 return posix_error();
1792
1793 slave_fd = open(slave_name, O_RDWR);
1794 if (slave_fd < 0)
1795 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001796#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001797
Fred Drake8cef4cf2000-06-28 16:40:38 +00001798 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001799
Fred Drake8cef4cf2000-06-28 16:40:38 +00001800}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001801#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001802
1803#ifdef HAVE_FORKPTY
1804static char posix_forkpty__doc__[] =
1805"forkpty() -> (pid, master_fd)\n\
1806Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1807Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1808To both, return fd of newly opened pseudo-terminal.\n";
1809
1810static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001811posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001812{
1813 int master_fd, pid;
1814
1815 if (!PyArg_ParseTuple(args, ":forkpty"))
1816 return NULL;
1817 pid = forkpty(&master_fd, NULL, NULL, NULL);
1818 if (pid == -1)
1819 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001820 if (pid == 0)
1821 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001822 return Py_BuildValue("(ii)", pid, master_fd);
1823}
1824#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001825
Guido van Rossumad0ee831995-03-01 10:34:45 +00001826#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001827static char posix_getegid__doc__[] =
1828"getegid() -> egid\n\
1829Return the current process's effective group id.";
1830
Barry Warsaw53699e91996-12-10 23:23:01 +00001831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001832posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001833{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001834 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001835 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001836 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001837}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001838#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001839
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001840
Guido van Rossumad0ee831995-03-01 10:34:45 +00001841#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001842static char posix_geteuid__doc__[] =
1843"geteuid() -> euid\n\
1844Return the current process's effective user id.";
1845
Barry Warsaw53699e91996-12-10 23:23:01 +00001846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001847posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001848{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001849 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001850 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001851 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001852}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001853#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001855
Guido van Rossumad0ee831995-03-01 10:34:45 +00001856#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001857static char posix_getgid__doc__[] =
1858"getgid() -> gid\n\
1859Return the current process's group id.";
1860
Barry Warsaw53699e91996-12-10 23:23:01 +00001861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001862posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001863{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001864 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001865 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001866 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001867}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001868#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001870
1871static char posix_getpid__doc__[] =
1872"getpid() -> pid\n\
1873Return the current process id";
1874
Barry Warsaw53699e91996-12-10 23:23:01 +00001875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001876posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001877{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001878 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001879 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001880 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001881}
1882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001883
Fred Drakec9680921999-12-13 16:37:25 +00001884#ifdef HAVE_GETGROUPS
1885static char posix_getgroups__doc__[] = "\
1886getgroups() -> list of group IDs\n\
1887Return list of supplemental group IDs for the process.";
1888
1889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001890posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001891{
1892 PyObject *result = NULL;
1893
1894 if (PyArg_ParseTuple(args, ":getgroups")) {
1895#ifdef NGROUPS_MAX
1896#define MAX_GROUPS NGROUPS_MAX
1897#else
1898 /* defined to be 16 on Solaris7, so this should be a small number */
1899#define MAX_GROUPS 64
1900#endif
1901 gid_t grouplist[MAX_GROUPS];
1902 int n;
1903
1904 n = getgroups(MAX_GROUPS, grouplist);
1905 if (n < 0)
1906 posix_error();
1907 else {
1908 result = PyList_New(n);
1909 if (result != NULL) {
1910 PyObject *o;
1911 int i;
1912 for (i = 0; i < n; ++i) {
1913 o = PyInt_FromLong((long)grouplist[i]);
1914 if (o == NULL) {
1915 Py_DECREF(result);
1916 result = NULL;
1917 break;
1918 }
1919 PyList_SET_ITEM(result, i, o);
1920 }
1921 }
1922 }
1923 }
1924 return result;
1925}
1926#endif
1927
Guido van Rossumb6775db1994-08-01 11:34:53 +00001928#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001929static char posix_getpgrp__doc__[] =
1930"getpgrp() -> pgrp\n\
1931Return the current process group id.";
1932
Barry Warsaw53699e91996-12-10 23:23:01 +00001933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001934posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001935{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001936 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001937 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001938#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001939 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001940#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001941 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001942#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001943}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001944#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001946
Guido van Rossumb6775db1994-08-01 11:34:53 +00001947#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001948static char posix_setpgrp__doc__[] =
1949"setpgrp() -> None\n\
1950Make this process a session leader.";
1951
Barry Warsaw53699e91996-12-10 23:23:01 +00001952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001953posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001954{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001955 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001956 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001957#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001958 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001959#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001960 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001961#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001962 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001963 Py_INCREF(Py_None);
1964 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001965}
1966
Guido van Rossumb6775db1994-08-01 11:34:53 +00001967#endif /* HAVE_SETPGRP */
1968
Guido van Rossumad0ee831995-03-01 10:34:45 +00001969#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001970static char posix_getppid__doc__[] =
1971"getppid() -> ppid\n\
1972Return the parent's process id.";
1973
Barry Warsaw53699e91996-12-10 23:23:01 +00001974static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001975posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001976{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001977 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001978 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001979 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001980}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001981#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001983
Fred Drake12c6e2d1999-12-14 21:25:03 +00001984#ifdef HAVE_GETLOGIN
1985static char posix_getlogin__doc__[] = "\
1986getlogin() -> string\n\
1987Return the actual login name.";
1988
1989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001990posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001991{
1992 PyObject *result = NULL;
1993
1994 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00001995 char *name;
1996 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001997
Fred Drakea30680b2000-12-06 21:24:28 +00001998 errno = 0;
1999 name = getlogin();
2000 if (name == NULL) {
2001 if (errno)
2002 posix_error();
2003 else
2004 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002005 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002006 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002007 else
2008 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002009 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002010 }
2011 return result;
2012}
2013#endif
2014
Guido van Rossumad0ee831995-03-01 10:34:45 +00002015#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002016static char posix_getuid__doc__[] =
2017"getuid() -> uid\n\
2018Return the current process's user id.";
2019
Barry Warsaw53699e91996-12-10 23:23:01 +00002020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002021posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002022{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002023 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002024 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002025 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002026}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002027#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002029
Guido van Rossumad0ee831995-03-01 10:34:45 +00002030#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002031static char posix_kill__doc__[] =
2032"kill(pid, sig) -> None\n\
2033Kill a process with a signal.";
2034
Barry Warsaw53699e91996-12-10 23:23:01 +00002035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002036posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002037{
2038 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002039 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002040 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002041#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002042 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2043 APIRET rc;
2044 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002045 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002046
2047 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2048 APIRET rc;
2049 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002050 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002051
2052 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002053 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002054#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002055 if (kill(pid, sig) == -1)
2056 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002057#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002058 Py_INCREF(Py_None);
2059 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002060}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002061#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002062
Guido van Rossumc0125471996-06-28 18:55:32 +00002063#ifdef HAVE_PLOCK
2064
2065#ifdef HAVE_SYS_LOCK_H
2066#include <sys/lock.h>
2067#endif
2068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002069static char posix_plock__doc__[] =
2070"plock(op) -> None\n\
2071Lock program segments into memory.";
2072
Barry Warsaw53699e91996-12-10 23:23:01 +00002073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002074posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002075{
2076 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002077 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002078 return NULL;
2079 if (plock(op) == -1)
2080 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002081 Py_INCREF(Py_None);
2082 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002083}
2084#endif
2085
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002086
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002087#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002088static char posix_popen__doc__[] =
2089"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2090Open a pipe to/from a command returning a file object.";
2091
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002092#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002093static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002094async_system(const char *command)
2095{
2096 char *p, errormsg[256], args[1024];
2097 RESULTCODES rcodes;
2098 APIRET rc;
2099 char *shell = getenv("COMSPEC");
2100 if (!shell)
2101 shell = "cmd";
2102
2103 strcpy(args, shell);
2104 p = &args[ strlen(args)+1 ];
2105 strcpy(p, "/c ");
2106 strcat(p, command);
2107 p += strlen(p) + 1;
2108 *p = '\0';
2109
2110 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002111 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002112 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002113 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002114 &rcodes, shell);
2115 return rc;
2116}
2117
Guido van Rossumd48f2521997-12-05 22:19:34 +00002118static FILE *
2119popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002120{
2121 HFILE rhan, whan;
2122 FILE *retfd = NULL;
2123 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2124
Guido van Rossumd48f2521997-12-05 22:19:34 +00002125 if (rc != NO_ERROR) {
2126 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002127 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002128 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002129
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002130 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2131 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002132
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002133 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2134 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002135
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002136 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2137 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002138
2139 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002140 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002141 }
2142
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002143 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2144 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002145
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002146 close(oldfd); /* And Close Saved STDOUT Handle */
2147 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002148
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002149 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2150 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002151
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002152 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2153 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002154
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002155 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2156 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002157
2158 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002159 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002160 }
2161
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002162 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2163 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002164
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002165 close(oldfd); /* And Close Saved STDIN Handle */
2166 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002167
Guido van Rossumd48f2521997-12-05 22:19:34 +00002168 } else {
2169 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002170 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002171 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002172}
2173
2174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002175posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002176{
2177 char *name;
2178 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002179 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002180 FILE *fp;
2181 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002182 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002183 return NULL;
2184 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002185 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002186 Py_END_ALLOW_THREADS
2187 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002188 return os2_error(err);
2189
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002190 f = PyFile_FromFile(fp, name, mode, fclose);
2191 if (f != NULL)
2192 PyFile_SetBufSize(f, bufsize);
2193 return f;
2194}
2195
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002196#elif defined(MS_WIN32)
2197
2198/*
2199 * Portable 'popen' replacement for Win32.
2200 *
2201 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2202 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002203 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002204 */
2205
2206#include <malloc.h>
2207#include <io.h>
2208#include <fcntl.h>
2209
2210/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2211#define POPEN_1 1
2212#define POPEN_2 2
2213#define POPEN_3 3
2214#define POPEN_4 4
2215
2216static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002217static int _PyPclose(FILE *file);
2218
2219/*
2220 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002221 * for use when retrieving the process exit code. See _PyPclose() below
2222 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002223 */
2224static PyObject *_PyPopenProcs = NULL;
2225
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002226
2227/* popen that works from a GUI.
2228 *
2229 * The result of this function is a pipe (file) connected to the
2230 * processes stdin or stdout, depending on the requested mode.
2231 */
2232
2233static PyObject *
2234posix_popen(PyObject *self, PyObject *args)
2235{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002236 PyObject *f, *s;
2237 int tm = 0;
2238
2239 char *cmdstring;
2240 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002241 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002242 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002243 return NULL;
2244
2245 s = PyTuple_New(0);
2246
2247 if (*mode == 'r')
2248 tm = _O_RDONLY;
2249 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002250 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002251 return NULL;
2252 } else
2253 tm = _O_WRONLY;
2254
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002255 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002256 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002257 return NULL;
2258 }
2259
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002260 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002261 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002262 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002263 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002264 else
2265 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2266
2267 return f;
2268}
2269
2270/* Variation on win32pipe.popen
2271 *
2272 * The result of this function is a pipe (file) connected to the
2273 * process's stdin, and a pipe connected to the process's stdout.
2274 */
2275
2276static PyObject *
2277win32_popen2(PyObject *self, PyObject *args)
2278{
2279 PyObject *f;
2280 int tm=0;
2281
2282 char *cmdstring;
2283 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002284 int bufsize = -1;
2285 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002286 return NULL;
2287
2288 if (*mode == 't')
2289 tm = _O_TEXT;
2290 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002291 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002292 return NULL;
2293 } else
2294 tm = _O_BINARY;
2295
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002296 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002297 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002298 return NULL;
2299 }
2300
2301 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002302
2303 return f;
2304}
2305
2306/*
2307 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002308 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002309 * The result of this function is 3 pipes - the process's stdin,
2310 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002311 */
2312
2313static PyObject *
2314win32_popen3(PyObject *self, PyObject *args)
2315{
2316 PyObject *f;
2317 int tm = 0;
2318
2319 char *cmdstring;
2320 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002321 int bufsize = -1;
2322 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002323 return NULL;
2324
2325 if (*mode == 't')
2326 tm = _O_TEXT;
2327 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002328 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002329 return NULL;
2330 } else
2331 tm = _O_BINARY;
2332
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002333 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002334 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002335 return NULL;
2336 }
2337
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002338 f = _PyPopen(cmdstring, tm, POPEN_3);
2339
2340 return f;
2341}
2342
2343/*
2344 * Variation on win32pipe.popen
2345 *
2346 * The result of this function is 2 pipes - the processes stdin,
2347 * and stdout+stderr combined as a single pipe.
2348 */
2349
2350static PyObject *
2351win32_popen4(PyObject *self, PyObject *args)
2352{
2353 PyObject *f;
2354 int tm = 0;
2355
2356 char *cmdstring;
2357 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002358 int bufsize = -1;
2359 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002360 return NULL;
2361
2362 if (*mode == 't')
2363 tm = _O_TEXT;
2364 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002365 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002366 return NULL;
2367 } else
2368 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002369
2370 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002371 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002372 return NULL;
2373 }
2374
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002375 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002376
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002377 return f;
2378}
2379
Mark Hammond08501372001-01-31 07:30:29 +00002380static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002381_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002382 HANDLE hStdin,
2383 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002384 HANDLE hStderr,
2385 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002386{
2387 PROCESS_INFORMATION piProcInfo;
2388 STARTUPINFO siStartInfo;
2389 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002390 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002391 int i;
2392 int x;
2393
2394 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2395 s1 = (char *)_alloca(i);
2396 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2397 return x;
2398 if (GetVersion() < 0x80000000) {
2399 /*
2400 * NT/2000
2401 */
2402 x = i + strlen(s3) + strlen(cmdstring) + 1;
2403 s2 = (char *)_alloca(x);
2404 ZeroMemory(s2, x);
2405 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2406 }
2407 else {
2408 /*
2409 * Oh gag, we're on Win9x. Use the workaround listed in
2410 * KB: Q150956
2411 */
Mark Hammond08501372001-01-31 07:30:29 +00002412 char modulepath[_MAX_PATH];
2413 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002414 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2415 for (i = x = 0; modulepath[i]; i++)
2416 if (modulepath[i] == '\\')
2417 x = i+1;
2418 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002419 /* Create the full-name to w9xpopen, so we can test it exists */
2420 strncat(modulepath,
2421 szConsoleSpawn,
2422 (sizeof(modulepath)/sizeof(modulepath[0]))
2423 -strlen(modulepath));
2424 if (stat(modulepath, &statinfo) != 0) {
2425 /* Eeek - file-not-found - possibly an embedding
2426 situation - see if we can locate it in sys.prefix
2427 */
2428 strncpy(modulepath,
2429 Py_GetExecPrefix(),
2430 sizeof(modulepath)/sizeof(modulepath[0]));
2431 if (modulepath[strlen(modulepath)-1] != '\\')
2432 strcat(modulepath, "\\");
2433 strncat(modulepath,
2434 szConsoleSpawn,
2435 (sizeof(modulepath)/sizeof(modulepath[0]))
2436 -strlen(modulepath));
2437 /* No where else to look - raise an easily identifiable
2438 error, rather than leaving Windows to report
2439 "file not found" - as the user is probably blissfully
2440 unaware this shim EXE is used, and it will confuse them.
2441 (well, it confused me for a while ;-)
2442 */
2443 if (stat(modulepath, &statinfo) != 0) {
2444 PyErr_Format(PyExc_RuntimeError,
2445 "Can not locate '%s' which is needed "
2446 "for popen to work on this platform.",
2447 szConsoleSpawn);
2448 return FALSE;
2449 }
2450 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002451 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2452 strlen(modulepath) +
2453 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002454
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002455 s2 = (char *)_alloca(x);
2456 ZeroMemory(s2, x);
2457 sprintf(
2458 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002459 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002460 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002461 s1,
2462 s3,
2463 cmdstring);
2464 }
2465 }
2466
2467 /* Could be an else here to try cmd.exe / command.com in the path
2468 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002469 else {
2470 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2471 return FALSE;
2472 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002473
2474 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2475 siStartInfo.cb = sizeof(STARTUPINFO);
2476 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2477 siStartInfo.hStdInput = hStdin;
2478 siStartInfo.hStdOutput = hStdout;
2479 siStartInfo.hStdError = hStderr;
2480 siStartInfo.wShowWindow = SW_HIDE;
2481
2482 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002483 s2,
2484 NULL,
2485 NULL,
2486 TRUE,
2487 CREATE_NEW_CONSOLE,
2488 NULL,
2489 NULL,
2490 &siStartInfo,
2491 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002492 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002493 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002494
Mark Hammondb37a3732000-08-14 04:47:33 +00002495 /* Return process handle */
2496 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002497 return TRUE;
2498 }
Mark Hammond08501372001-01-31 07:30:29 +00002499 win32_error("CreateProcess", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002500 return FALSE;
2501}
2502
2503/* The following code is based off of KB: Q190351 */
2504
2505static PyObject *
2506_PyPopen(char *cmdstring, int mode, int n)
2507{
2508 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2509 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002510 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002511
2512 SECURITY_ATTRIBUTES saAttr;
2513 BOOL fSuccess;
2514 int fd1, fd2, fd3;
2515 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002516 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002517 PyObject *f;
2518
2519 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2520 saAttr.bInheritHandle = TRUE;
2521 saAttr.lpSecurityDescriptor = NULL;
2522
2523 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2524 return win32_error("CreatePipe", NULL);
2525
2526 /* Create new output read handle and the input write handle. Set
2527 * the inheritance properties to FALSE. Otherwise, the child inherits
2528 * the these handles; resulting in non-closeable handles to the pipes
2529 * being created. */
2530 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002531 GetCurrentProcess(), &hChildStdinWrDup, 0,
2532 FALSE,
2533 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002534 if (!fSuccess)
2535 return win32_error("DuplicateHandle", NULL);
2536
2537 /* Close the inheritable version of ChildStdin
2538 that we're using. */
2539 CloseHandle(hChildStdinWr);
2540
2541 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2542 return win32_error("CreatePipe", NULL);
2543
2544 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002545 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2546 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002547 if (!fSuccess)
2548 return win32_error("DuplicateHandle", NULL);
2549
2550 /* Close the inheritable version of ChildStdout
2551 that we're using. */
2552 CloseHandle(hChildStdoutRd);
2553
2554 if (n != POPEN_4) {
2555 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2556 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002557 fSuccess = DuplicateHandle(GetCurrentProcess(),
2558 hChildStderrRd,
2559 GetCurrentProcess(),
2560 &hChildStderrRdDup, 0,
2561 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002562 if (!fSuccess)
2563 return win32_error("DuplicateHandle", NULL);
2564 /* Close the inheritable version of ChildStdErr that we're using. */
2565 CloseHandle(hChildStderrRd);
2566 }
2567
2568 switch (n) {
2569 case POPEN_1:
2570 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2571 case _O_WRONLY | _O_TEXT:
2572 /* Case for writing to child Stdin in text mode. */
2573 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2574 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002575 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002576 PyFile_SetBufSize(f, 0);
2577 /* We don't care about these pipes anymore, so close them. */
2578 CloseHandle(hChildStdoutRdDup);
2579 CloseHandle(hChildStderrRdDup);
2580 break;
2581
2582 case _O_RDONLY | _O_TEXT:
2583 /* Case for reading from child Stdout in text mode. */
2584 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2585 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002586 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002587 PyFile_SetBufSize(f, 0);
2588 /* We don't care about these pipes anymore, so close them. */
2589 CloseHandle(hChildStdinWrDup);
2590 CloseHandle(hChildStderrRdDup);
2591 break;
2592
2593 case _O_RDONLY | _O_BINARY:
2594 /* Case for readinig from child Stdout in binary mode. */
2595 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2596 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002597 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002598 PyFile_SetBufSize(f, 0);
2599 /* We don't care about these pipes anymore, so close them. */
2600 CloseHandle(hChildStdinWrDup);
2601 CloseHandle(hChildStderrRdDup);
2602 break;
2603
2604 case _O_WRONLY | _O_BINARY:
2605 /* Case for writing to child Stdin in binary mode. */
2606 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2607 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002608 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002609 PyFile_SetBufSize(f, 0);
2610 /* We don't care about these pipes anymore, so close them. */
2611 CloseHandle(hChildStdoutRdDup);
2612 CloseHandle(hChildStderrRdDup);
2613 break;
2614 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002615 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002616 break;
2617
2618 case POPEN_2:
2619 case POPEN_4:
2620 {
2621 char *m1, *m2;
2622 PyObject *p1, *p2;
2623
2624 if (mode && _O_TEXT) {
2625 m1 = "r";
2626 m2 = "w";
2627 } else {
2628 m1 = "rb";
2629 m2 = "wb";
2630 }
2631
2632 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2633 f1 = _fdopen(fd1, m2);
2634 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2635 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002636 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002637 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002638 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002639 PyFile_SetBufSize(p2, 0);
2640
2641 if (n != 4)
2642 CloseHandle(hChildStderrRdDup);
2643
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002644 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002645 Py_XDECREF(p1);
2646 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002647 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002648 break;
2649 }
2650
2651 case POPEN_3:
2652 {
2653 char *m1, *m2;
2654 PyObject *p1, *p2, *p3;
2655
2656 if (mode && _O_TEXT) {
2657 m1 = "r";
2658 m2 = "w";
2659 } else {
2660 m1 = "rb";
2661 m2 = "wb";
2662 }
2663
2664 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2665 f1 = _fdopen(fd1, m2);
2666 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2667 f2 = _fdopen(fd2, m1);
2668 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2669 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002670 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002671 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2672 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002673 PyFile_SetBufSize(p1, 0);
2674 PyFile_SetBufSize(p2, 0);
2675 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002676 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002677 Py_XDECREF(p1);
2678 Py_XDECREF(p2);
2679 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002680 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002681 break;
2682 }
2683 }
2684
2685 if (n == POPEN_4) {
2686 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002687 hChildStdinRd,
2688 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002689 hChildStdoutWr,
2690 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002691 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002692 }
2693 else {
2694 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002695 hChildStdinRd,
2696 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002697 hChildStderrWr,
2698 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002699 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002700 }
2701
Mark Hammondb37a3732000-08-14 04:47:33 +00002702 /*
2703 * Insert the files we've created into the process dictionary
2704 * all referencing the list with the process handle and the
2705 * initial number of files (see description below in _PyPclose).
2706 * Since if _PyPclose later tried to wait on a process when all
2707 * handles weren't closed, it could create a deadlock with the
2708 * child, we spend some energy here to try to ensure that we
2709 * either insert all file handles into the dictionary or none
2710 * at all. It's a little clumsy with the various popen modes
2711 * and variable number of files involved.
2712 */
2713 if (!_PyPopenProcs) {
2714 _PyPopenProcs = PyDict_New();
2715 }
2716
2717 if (_PyPopenProcs) {
2718 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2719 int ins_rc[3];
2720
2721 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2722 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2723
2724 procObj = PyList_New(2);
2725 hProcessObj = PyLong_FromVoidPtr(hProcess);
2726 intObj = PyInt_FromLong(file_count);
2727
2728 if (procObj && hProcessObj && intObj) {
2729 PyList_SetItem(procObj,0,hProcessObj);
2730 PyList_SetItem(procObj,1,intObj);
2731
2732 fileObj[0] = PyLong_FromVoidPtr(f1);
2733 if (fileObj[0]) {
2734 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2735 fileObj[0],
2736 procObj);
2737 }
2738 if (file_count >= 2) {
2739 fileObj[1] = PyLong_FromVoidPtr(f2);
2740 if (fileObj[1]) {
2741 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2742 fileObj[1],
2743 procObj);
2744 }
2745 }
2746 if (file_count >= 3) {
2747 fileObj[2] = PyLong_FromVoidPtr(f3);
2748 if (fileObj[2]) {
2749 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2750 fileObj[2],
2751 procObj);
2752 }
2753 }
2754
2755 if (ins_rc[0] < 0 || !fileObj[0] ||
2756 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2757 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2758 /* Something failed - remove any dictionary
2759 * entries that did make it.
2760 */
2761 if (!ins_rc[0] && fileObj[0]) {
2762 PyDict_DelItem(_PyPopenProcs,
2763 fileObj[0]);
2764 }
2765 if (!ins_rc[1] && fileObj[1]) {
2766 PyDict_DelItem(_PyPopenProcs,
2767 fileObj[1]);
2768 }
2769 if (!ins_rc[2] && fileObj[2]) {
2770 PyDict_DelItem(_PyPopenProcs,
2771 fileObj[2]);
2772 }
2773 }
2774 }
2775
2776 /*
2777 * Clean up our localized references for the dictionary keys
2778 * and value since PyDict_SetItem will Py_INCREF any copies
2779 * that got placed in the dictionary.
2780 */
2781 Py_XDECREF(procObj);
2782 Py_XDECREF(fileObj[0]);
2783 Py_XDECREF(fileObj[1]);
2784 Py_XDECREF(fileObj[2]);
2785 }
2786
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002787 /* Child is launched. Close the parents copy of those pipe
2788 * handles that only the child should have open. You need to
2789 * make sure that no handles to the write end of the output pipe
2790 * are maintained in this process or else the pipe will not close
2791 * when the child process exits and the ReadFile will hang. */
2792
2793 if (!CloseHandle(hChildStdinRd))
2794 return win32_error("CloseHandle", NULL);
2795
2796 if (!CloseHandle(hChildStdoutWr))
2797 return win32_error("CloseHandle", NULL);
2798
2799 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2800 return win32_error("CloseHandle", NULL);
2801
2802 return f;
2803}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002804
2805/*
2806 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2807 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002808 *
2809 * This function uses the _PyPopenProcs dictionary in order to map the
2810 * input file pointer to information about the process that was
2811 * originally created by the popen* call that created the file pointer.
2812 * The dictionary uses the file pointer as a key (with one entry
2813 * inserted for each file returned by the original popen* call) and a
2814 * single list object as the value for all files from a single call.
2815 * The list object contains the Win32 process handle at [0], and a file
2816 * count at [1], which is initialized to the total number of file
2817 * handles using that list.
2818 *
2819 * This function closes whichever handle it is passed, and decrements
2820 * the file count in the dictionary for the process handle pointed to
2821 * by this file. On the last close (when the file count reaches zero),
2822 * this function will wait for the child process and then return its
2823 * exit code as the result of the close() operation. This permits the
2824 * files to be closed in any order - it is always the close() of the
2825 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002826 */
Tim Peters736aa322000-09-01 06:51:24 +00002827
2828 /* RED_FLAG 31-Aug-2000 Tim
2829 * This is always called (today!) between a pair of
2830 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2831 * macros. So the thread running this has no valid thread state, as
2832 * far as Python is concerned. However, this calls some Python API
2833 * functions that cannot be called safely without a valid thread
2834 * state, in particular PyDict_GetItem.
2835 * As a temporary hack (although it may last for years ...), we
2836 * *rely* on not having a valid thread state in this function, in
2837 * order to create our own "from scratch".
2838 * This will deadlock if _PyPclose is ever called by a thread
2839 * holding the global lock.
2840 */
2841
Fredrik Lundh56055a42000-07-23 19:47:12 +00002842static int _PyPclose(FILE *file)
2843{
Fredrik Lundh20318932000-07-26 17:29:12 +00002844 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002845 DWORD exit_code;
2846 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002847 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2848 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002849#ifdef WITH_THREAD
2850 PyInterpreterState* pInterpreterState;
2851 PyThreadState* pThreadState;
2852#endif
2853
Fredrik Lundh20318932000-07-26 17:29:12 +00002854 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002855 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002856 */
2857 result = fclose(file);
2858
Tim Peters736aa322000-09-01 06:51:24 +00002859#ifdef WITH_THREAD
2860 /* Bootstrap a valid thread state into existence. */
2861 pInterpreterState = PyInterpreterState_New();
2862 if (!pInterpreterState) {
2863 /* Well, we're hosed now! We don't have a thread
2864 * state, so can't call a nice error routine, or raise
2865 * an exception. Just die.
2866 */
2867 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002868 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002869 return -1; /* unreachable */
2870 }
2871 pThreadState = PyThreadState_New(pInterpreterState);
2872 if (!pThreadState) {
2873 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002874 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002875 return -1; /* unreachable */
2876 }
2877 /* Grab the global lock. Note that this will deadlock if the
2878 * current thread already has the lock! (see RED_FLAG comments
2879 * before this function)
2880 */
2881 PyEval_RestoreThread(pThreadState);
2882#endif
2883
Fredrik Lundh56055a42000-07-23 19:47:12 +00002884 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002885 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2886 (procObj = PyDict_GetItem(_PyPopenProcs,
2887 fileObj)) != NULL &&
2888 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2889 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2890
2891 hProcess = PyLong_AsVoidPtr(hProcessObj);
2892 file_count = PyInt_AsLong(intObj);
2893
2894 if (file_count > 1) {
2895 /* Still other files referencing process */
2896 file_count--;
2897 PyList_SetItem(procObj,1,
2898 PyInt_FromLong(file_count));
2899 } else {
2900 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002901 if (result != EOF &&
2902 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2903 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002904 /* Possible truncation here in 16-bit environments, but
2905 * real exit codes are just the lower byte in any event.
2906 */
2907 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002908 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002909 /* Indicate failure - this will cause the file object
2910 * to raise an I/O error and translate the last Win32
2911 * error code from errno. We do have a problem with
2912 * last errors that overlap the normal errno table,
2913 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002914 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002915 if (result != EOF) {
2916 /* If the error wasn't from the fclose(), then
2917 * set errno for the file object error handling.
2918 */
2919 errno = GetLastError();
2920 }
2921 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002922 }
2923
2924 /* Free up the native handle at this point */
2925 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002926 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002927
Mark Hammondb37a3732000-08-14 04:47:33 +00002928 /* Remove this file pointer from dictionary */
2929 PyDict_DelItem(_PyPopenProcs, fileObj);
2930
2931 if (PyDict_Size(_PyPopenProcs) == 0) {
2932 Py_DECREF(_PyPopenProcs);
2933 _PyPopenProcs = NULL;
2934 }
2935
2936 } /* if object retrieval ok */
2937
2938 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002939 } /* if _PyPopenProcs */
2940
Tim Peters736aa322000-09-01 06:51:24 +00002941#ifdef WITH_THREAD
2942 /* Tear down the thread & interpreter states.
2943 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002944 * call the thread clear & delete functions, and indeed insist on
2945 * doing that themselves. The lock must be held during the clear, but
2946 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002947 */
2948 PyInterpreterState_Clear(pInterpreterState);
2949 PyEval_ReleaseThread(pThreadState);
2950 PyInterpreterState_Delete(pInterpreterState);
2951#endif
2952
Fredrik Lundh56055a42000-07-23 19:47:12 +00002953 return result;
2954}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002955
2956#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002958posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002959{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002960 char *name;
2961 char *mode = "r";
2962 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002963 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002964 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002965 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002966 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002967 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002968 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002969 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002970 if (fp == NULL)
2971 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002972 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002973 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002974 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002975 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002976}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002977#endif
2978
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002979#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002980
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002981
Guido van Rossumb6775db1994-08-01 11:34:53 +00002982#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002983static char posix_setuid__doc__[] =
2984"setuid(uid) -> None\n\
2985Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002987posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002988{
2989 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002990 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002991 return NULL;
2992 if (setuid(uid) < 0)
2993 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002994 Py_INCREF(Py_None);
2995 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002996}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002997#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002999
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003000#ifdef HAVE_SETEUID
3001static char posix_seteuid__doc__[] =
3002"seteuid(uid) -> None\n\
3003Set the current process's effective user id.";
3004static PyObject *
3005posix_seteuid (PyObject *self, PyObject *args)
3006{
3007 int euid;
3008 if (!PyArg_ParseTuple(args, "i", &euid)) {
3009 return NULL;
3010 } else if (seteuid(euid) < 0) {
3011 return posix_error();
3012 } else {
3013 Py_INCREF(Py_None);
3014 return Py_None;
3015 }
3016}
3017#endif /* HAVE_SETEUID */
3018
3019#ifdef HAVE_SETEGID
3020static char posix_setegid__doc__[] =
3021"setegid(gid) -> None\n\
3022Set the current process's effective group id.";
3023static PyObject *
3024posix_setegid (PyObject *self, PyObject *args)
3025{
3026 int egid;
3027 if (!PyArg_ParseTuple(args, "i", &egid)) {
3028 return NULL;
3029 } else if (setegid(egid) < 0) {
3030 return posix_error();
3031 } else {
3032 Py_INCREF(Py_None);
3033 return Py_None;
3034 }
3035}
3036#endif /* HAVE_SETEGID */
3037
3038#ifdef HAVE_SETREUID
3039static char posix_setreuid__doc__[] =
3040"seteuid(ruid, euid) -> None\n\
3041Set the current process's real and effective user ids.";
3042static PyObject *
3043posix_setreuid (PyObject *self, PyObject *args)
3044{
3045 int ruid, euid;
3046 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3047 return NULL;
3048 } else if (setreuid(ruid, euid) < 0) {
3049 return posix_error();
3050 } else {
3051 Py_INCREF(Py_None);
3052 return Py_None;
3053 }
3054}
3055#endif /* HAVE_SETREUID */
3056
3057#ifdef HAVE_SETREGID
3058static char posix_setregid__doc__[] =
3059"setegid(rgid, egid) -> None\n\
3060Set the current process's real and effective group ids.";
3061static PyObject *
3062posix_setregid (PyObject *self, PyObject *args)
3063{
3064 int rgid, egid;
3065 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3066 return NULL;
3067 } else if (setregid(rgid, egid) < 0) {
3068 return posix_error();
3069 } else {
3070 Py_INCREF(Py_None);
3071 return Py_None;
3072 }
3073}
3074#endif /* HAVE_SETREGID */
3075
Guido van Rossumb6775db1994-08-01 11:34:53 +00003076#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003077static char posix_setgid__doc__[] =
3078"setgid(gid) -> None\n\
3079Set the current process's group id.";
3080
Barry Warsaw53699e91996-12-10 23:23:01 +00003081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003082posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003083{
3084 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003085 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003086 return NULL;
3087 if (setgid(gid) < 0)
3088 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003089 Py_INCREF(Py_None);
3090 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003091}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003092#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003093
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003094
Guido van Rossumb6775db1994-08-01 11:34:53 +00003095#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003096static char posix_waitpid__doc__[] =
3097"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003098Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003099
Barry Warsaw53699e91996-12-10 23:23:01 +00003100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003101posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003102{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003103 int pid, options;
3104#ifdef UNION_WAIT
3105 union wait status;
3106#define status_i (status.w_status)
3107#else
3108 int status;
3109#define status_i status
3110#endif
3111 status_i = 0;
3112
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003113 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003114 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003115 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003116#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003117 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003118#else
3119 pid = waitpid(pid, &status, options);
3120#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003121 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003122 if (pid == -1)
3123 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003124 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003125 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003126}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003127#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003128
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003129
Guido van Rossumad0ee831995-03-01 10:34:45 +00003130#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003131static char posix_wait__doc__[] =
3132"wait() -> (pid, status)\n\
3133Wait for completion of a child process.";
3134
Barry Warsaw53699e91996-12-10 23:23:01 +00003135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003136posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003137{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003138 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003139#ifdef UNION_WAIT
3140 union wait status;
3141#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003142#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003143 int status;
3144#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003145#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003146 if (!PyArg_ParseTuple(args, ":wait"))
3147 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003148 status_i = 0;
3149 Py_BEGIN_ALLOW_THREADS
3150 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003151 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003152 if (pid == -1)
3153 return posix_error();
3154 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003155 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003156#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003157}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003158#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003160
3161static char posix_lstat__doc__[] =
3162"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3163Like stat(path), but do not follow symbolic links.";
3164
Barry Warsaw53699e91996-12-10 23:23:01 +00003165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003166posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003167{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003168#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003169 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003170#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003171 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003172#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003173}
3174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Guido van Rossumb6775db1994-08-01 11:34:53 +00003176#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003177static char posix_readlink__doc__[] =
3178"readlink(path) -> path\n\
3179Return a string representing the path to which the symbolic link points.";
3180
Barry Warsaw53699e91996-12-10 23:23:01 +00003181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003182posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003183{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003184 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003185 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003186 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003187 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003188 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003189 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003190 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003191 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003192 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003193 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003194 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003195}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003196#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003197
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003198
Guido van Rossumb6775db1994-08-01 11:34:53 +00003199#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003200static char posix_symlink__doc__[] =
3201"symlink(src, dst) -> None\n\
3202Create a symbolic link.";
3203
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003205posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003206{
Mark Hammondef8b6542001-05-13 08:04:26 +00003207 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003208}
3209#endif /* HAVE_SYMLINK */
3210
3211
3212#ifdef HAVE_TIMES
3213#ifndef HZ
3214#define HZ 60 /* Universal constant :-) */
3215#endif /* HZ */
3216
Guido van Rossumd48f2521997-12-05 22:19:34 +00003217#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3218static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003219system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003220{
3221 ULONG value = 0;
3222
3223 Py_BEGIN_ALLOW_THREADS
3224 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3225 Py_END_ALLOW_THREADS
3226
3227 return value;
3228}
3229
3230static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003231posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003232{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003233 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003234 return NULL;
3235
3236 /* Currently Only Uptime is Provided -- Others Later */
3237 return Py_BuildValue("ddddd",
3238 (double)0 /* t.tms_utime / HZ */,
3239 (double)0 /* t.tms_stime / HZ */,
3240 (double)0 /* t.tms_cutime / HZ */,
3241 (double)0 /* t.tms_cstime / HZ */,
3242 (double)system_uptime() / 1000);
3243}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003244#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003245static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003246posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003247{
3248 struct tms t;
3249 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003250 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003251 return NULL;
3252 errno = 0;
3253 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003254 if (c == (clock_t) -1)
3255 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003256 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003257 (double)t.tms_utime / HZ,
3258 (double)t.tms_stime / HZ,
3259 (double)t.tms_cutime / HZ,
3260 (double)t.tms_cstime / HZ,
3261 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003262}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003263#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003264#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003265
3266
Guido van Rossum87755a21996-09-07 00:59:43 +00003267#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003268#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003270posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003271{
3272 FILETIME create, exit, kernel, user;
3273 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003274 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003275 return NULL;
3276 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003277 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3278 /* The fields of a FILETIME structure are the hi and lo part
3279 of a 64-bit value expressed in 100 nanosecond units.
3280 1e7 is one second in such units; 1e-7 the inverse.
3281 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3282 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003283 return Py_BuildValue(
3284 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003285 (double)(kernel.dwHighDateTime*429.4967296 +
3286 kernel.dwLowDateTime*1e-7),
3287 (double)(user.dwHighDateTime*429.4967296 +
3288 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003289 (double)0,
3290 (double)0,
3291 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003292}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003293#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003294
3295#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003296static char posix_times__doc__[] =
3297"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3298Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003299#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003301
Guido van Rossumb6775db1994-08-01 11:34:53 +00003302#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003303static char posix_setsid__doc__[] =
3304"setsid() -> None\n\
3305Call the system call setsid().";
3306
Barry Warsaw53699e91996-12-10 23:23:01 +00003307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003308posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003309{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003310 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003311 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003312 if (setsid() < 0)
3313 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003314 Py_INCREF(Py_None);
3315 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003316}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003317#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003318
Guido van Rossumb6775db1994-08-01 11:34:53 +00003319#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003320static char posix_setpgid__doc__[] =
3321"setpgid(pid, pgrp) -> None\n\
3322Call the system call setpgid().";
3323
Barry Warsaw53699e91996-12-10 23:23:01 +00003324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003325posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003326{
3327 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003328 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003329 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003330 if (setpgid(pid, pgrp) < 0)
3331 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003332 Py_INCREF(Py_None);
3333 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003334}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003335#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003336
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003337
Guido van Rossumb6775db1994-08-01 11:34:53 +00003338#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003339static char posix_tcgetpgrp__doc__[] =
3340"tcgetpgrp(fd) -> pgid\n\
3341Return the process group associated with the terminal given by a fd.";
3342
Barry Warsaw53699e91996-12-10 23:23:01 +00003343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003344posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003345{
3346 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003347 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003348 return NULL;
3349 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003350 if (pgid < 0)
3351 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003352 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003353}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003354#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003356
Guido van Rossumb6775db1994-08-01 11:34:53 +00003357#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003358static char posix_tcsetpgrp__doc__[] =
3359"tcsetpgrp(fd, pgid) -> None\n\
3360Set the process group associated with the terminal given by a fd.";
3361
Barry Warsaw53699e91996-12-10 23:23:01 +00003362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003363posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003364{
3365 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003366 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003367 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003368 if (tcsetpgrp(fd, pgid) < 0)
3369 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003370 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003371 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003372}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003373#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003374
Guido van Rossum687dd131993-05-17 08:34:16 +00003375/* Functions acting on file descriptors */
3376
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003377static char posix_open__doc__[] =
3378"open(filename, flag [, mode=0777]) -> fd\n\
3379Open a file (for low level IO).";
3380
Barry Warsaw53699e91996-12-10 23:23:01 +00003381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003382posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003383{
Mark Hammondef8b6542001-05-13 08:04:26 +00003384 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003385 int flag;
3386 int mode = 0777;
3387 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003388 if (!PyArg_ParseTuple(args, "eti|i",
3389 Py_FileSystemDefaultEncoding, &file,
3390 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003391 return NULL;
3392
Barry Warsaw53699e91996-12-10 23:23:01 +00003393 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003394 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003395 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003396 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003397 return posix_error_with_allocated_filename(file);
3398 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003399 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003400}
3401
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003402
3403static char posix_close__doc__[] =
3404"close(fd) -> None\n\
3405Close a file descriptor (for low level IO).";
3406
Barry Warsaw53699e91996-12-10 23:23:01 +00003407static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003408posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003409{
3410 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003411 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003412 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003413 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003414 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003415 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003416 if (res < 0)
3417 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003418 Py_INCREF(Py_None);
3419 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003420}
3421
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003422
3423static char posix_dup__doc__[] =
3424"dup(fd) -> fd2\n\
3425Return a duplicate of a file descriptor.";
3426
Barry Warsaw53699e91996-12-10 23:23:01 +00003427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003428posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003429{
3430 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003431 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003432 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003433 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003434 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003435 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003436 if (fd < 0)
3437 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003438 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003439}
3440
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003441
3442static char posix_dup2__doc__[] =
3443"dup2(fd, fd2) -> None\n\
3444Duplicate file descriptor.";
3445
Barry Warsaw53699e91996-12-10 23:23:01 +00003446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003447posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003448{
3449 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003450 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003451 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003452 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003453 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003454 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003455 if (res < 0)
3456 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003457 Py_INCREF(Py_None);
3458 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003459}
3460
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003461
3462static char posix_lseek__doc__[] =
3463"lseek(fd, pos, how) -> newpos\n\
3464Set the current position of a file descriptor.";
3465
Barry Warsaw53699e91996-12-10 23:23:01 +00003466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003467posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003468{
3469 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003470#ifdef MS_WIN64
3471 LONG_LONG pos, res;
3472#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003473 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003474#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003475 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003476 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003477 return NULL;
3478#ifdef SEEK_SET
3479 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3480 switch (how) {
3481 case 0: how = SEEK_SET; break;
3482 case 1: how = SEEK_CUR; break;
3483 case 2: how = SEEK_END; break;
3484 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003485#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003486
3487#if !defined(HAVE_LARGEFILE_SUPPORT)
3488 pos = PyInt_AsLong(posobj);
3489#else
3490 pos = PyLong_Check(posobj) ?
3491 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3492#endif
3493 if (PyErr_Occurred())
3494 return NULL;
3495
Barry Warsaw53699e91996-12-10 23:23:01 +00003496 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003497#ifdef MS_WIN64
3498 res = _lseeki64(fd, pos, how);
3499#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003500 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003501#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003502 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003503 if (res < 0)
3504 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003505
3506#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003507 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003508#else
3509 return PyLong_FromLongLong(res);
3510#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003511}
3512
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003513
3514static char posix_read__doc__[] =
3515"read(fd, buffersize) -> string\n\
3516Read a file descriptor.";
3517
Barry Warsaw53699e91996-12-10 23:23:01 +00003518static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003519posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003520{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003521 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003522 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003523 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003524 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003525 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003526 if (buffer == NULL)
3527 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003528 Py_BEGIN_ALLOW_THREADS
3529 n = read(fd, PyString_AsString(buffer), size);
3530 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003531 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003532 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003533 return posix_error();
3534 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003535 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003536 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003537 return buffer;
3538}
3539
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003540
3541static char posix_write__doc__[] =
3542"write(fd, string) -> byteswritten\n\
3543Write a string to a file descriptor.";
3544
Barry Warsaw53699e91996-12-10 23:23:01 +00003545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003546posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003547{
3548 int fd, size;
3549 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003550 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003551 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003552 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003553 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003554 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003555 if (size < 0)
3556 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003557 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003558}
3559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003560
3561static char posix_fstat__doc__[]=
3562"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3563Like stat(), but for an open file descriptor.";
3564
Barry Warsaw53699e91996-12-10 23:23:01 +00003565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003566posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003567{
3568 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003569 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003570 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003571 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003572 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003573 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003574 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003575 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003576 if (res != 0)
3577 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003578
3579 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003580}
3581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003582
3583static char posix_fdopen__doc__[] =
3584"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3585Return an open file object connected to a file descriptor.";
3586
Barry Warsaw53699e91996-12-10 23:23:01 +00003587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003588posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003589{
Guido van Rossum687dd131993-05-17 08:34:16 +00003590 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003591 char *mode = "r";
3592 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003593 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003594 PyObject *f;
3595 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003596 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003597
Barry Warsaw53699e91996-12-10 23:23:01 +00003598 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003599 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003600 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003601 if (fp == NULL)
3602 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003603 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003604 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003605 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003606 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003607}
3608
Skip Montanaro1517d842000-07-19 14:34:14 +00003609static char posix_isatty__doc__[] =
3610"isatty(fd) -> Boolean\n\
3611Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003612connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003613
3614static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003615posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003616{
3617 int fd;
3618 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3619 return NULL;
3620 return Py_BuildValue("i", isatty(fd));
3621}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003622
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003623#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003624static char posix_pipe__doc__[] =
3625"pipe() -> (read_end, write_end)\n\
3626Create a pipe.";
3627
Barry Warsaw53699e91996-12-10 23:23:01 +00003628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003629posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003630{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003631#if defined(PYOS_OS2)
3632 HFILE read, write;
3633 APIRET rc;
3634
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003635 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003636 return NULL;
3637
3638 Py_BEGIN_ALLOW_THREADS
3639 rc = DosCreatePipe( &read, &write, 4096);
3640 Py_END_ALLOW_THREADS
3641 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003642 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003643
3644 return Py_BuildValue("(ii)", read, write);
3645#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003646#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003647 int fds[2];
3648 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003649 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003650 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003651 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003652 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003653 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003654 if (res != 0)
3655 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003656 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003657#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003658 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003659 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003660 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003661 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003662 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003663 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003664 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003665 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003666 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003667 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003668 read_fd = _open_osfhandle((intptr_t)read, 0);
3669 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003670 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003671#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003672#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003673}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003674#endif /* HAVE_PIPE */
3675
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003676
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003677#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003678static char posix_mkfifo__doc__[] =
3679"mkfifo(file, [, mode=0666]) -> None\n\
3680Create a FIFO (a POSIX named pipe).";
3681
Barry Warsaw53699e91996-12-10 23:23:01 +00003682static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003683posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003684{
3685 char *file;
3686 int mode = 0666;
3687 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003688 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003689 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003690 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003691 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003692 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003693 if (res < 0)
3694 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003695 Py_INCREF(Py_None);
3696 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003697}
3698#endif
3699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003700
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003701#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003702static char posix_ftruncate__doc__[] =
3703"ftruncate(fd, length) -> None\n\
3704Truncate a file to a specified length.";
3705
Barry Warsaw53699e91996-12-10 23:23:01 +00003706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003707posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003708{
3709 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003710 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003711 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003712 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003713
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003714 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003715 return NULL;
3716
3717#if !defined(HAVE_LARGEFILE_SUPPORT)
3718 length = PyInt_AsLong(lenobj);
3719#else
3720 length = PyLong_Check(lenobj) ?
3721 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3722#endif
3723 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003724 return NULL;
3725
Barry Warsaw53699e91996-12-10 23:23:01 +00003726 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003727 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003728 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003729 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003730 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003731 return NULL;
3732 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003733 Py_INCREF(Py_None);
3734 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003735}
3736#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003737
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003738#ifdef NeXT
3739#define HAVE_PUTENV
3740/* Steve Spicklemire got this putenv from NeXTAnswers */
3741static int
3742putenv(char *newval)
3743{
3744 extern char **environ;
3745
3746 static int firstTime = 1;
3747 char **ep;
3748 char *cp;
3749 int esiz;
3750 char *np;
3751
3752 if (!(np = strchr(newval, '=')))
3753 return 1;
3754 *np = '\0';
3755
3756 /* look it up */
3757 for (ep=environ ; *ep ; ep++)
3758 {
3759 /* this should always be true... */
3760 if (cp = strchr(*ep, '='))
3761 {
3762 *cp = '\0';
3763 if (!strcmp(*ep, newval))
3764 {
3765 /* got it! */
3766 *cp = '=';
3767 break;
3768 }
3769 *cp = '=';
3770 }
3771 else
3772 {
3773 *np = '=';
3774 return 1;
3775 }
3776 }
3777
3778 *np = '=';
3779 if (*ep)
3780 {
3781 /* the string was already there:
3782 just replace it with the new one */
3783 *ep = newval;
3784 return 0;
3785 }
3786
3787 /* expand environ by one */
3788 for (esiz=2, ep=environ ; *ep ; ep++)
3789 esiz++;
3790 if (firstTime)
3791 {
3792 char **epp;
3793 char **newenv;
3794 if (!(newenv = malloc(esiz * sizeof(char *))))
3795 return 1;
3796
3797 for (ep=environ, epp=newenv ; *ep ;)
3798 *epp++ = *ep++;
3799 *epp++ = newval;
3800 *epp = (char *) 0;
3801 environ = newenv;
3802 }
3803 else
3804 {
3805 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3806 return 1;
3807 environ[esiz - 2] = newval;
3808 environ[esiz - 1] = (char *) 0;
3809 firstTime = 0;
3810 }
3811
3812 return 0;
3813}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003814#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003815
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003816
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003817#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003818static char posix_putenv__doc__[] =
3819"putenv(key, value) -> None\n\
3820Change or add an environment variable.";
3821
Fred Drake762e2061999-08-26 17:23:54 +00003822/* Save putenv() parameters as values here, so we can collect them when they
3823 * get re-set with another call for the same key. */
3824static PyObject *posix_putenv_garbage;
3825
Barry Warsaw53699e91996-12-10 23:23:01 +00003826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003827posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003828{
3829 char *s1, *s2;
3830 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003831 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003832
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003833 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003834 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003835
3836#if defined(PYOS_OS2)
3837 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3838 APIRET rc;
3839
3840 if (strlen(s2) == 0) /* If New Value is an Empty String */
3841 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3842
3843 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3844 if (rc != NO_ERROR)
3845 return os2_error(rc);
3846
3847 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3848 APIRET rc;
3849
3850 if (strlen(s2) == 0) /* If New Value is an Empty String */
3851 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3852
3853 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3854 if (rc != NO_ERROR)
3855 return os2_error(rc);
3856 } else {
3857#endif
3858
Fred Drake762e2061999-08-26 17:23:54 +00003859 /* XXX This can leak memory -- not easy to fix :-( */
3860 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3861 if (newstr == NULL)
3862 return PyErr_NoMemory();
3863 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003864 (void) sprintf(new, "%s=%s", s1, s2);
3865 if (putenv(new)) {
3866 posix_error();
3867 return NULL;
3868 }
Fred Drake762e2061999-08-26 17:23:54 +00003869 /* Install the first arg and newstr in posix_putenv_garbage;
3870 * this will cause previous value to be collected. This has to
3871 * happen after the real putenv() call because the old value
3872 * was still accessible until then. */
3873 if (PyDict_SetItem(posix_putenv_garbage,
3874 PyTuple_GET_ITEM(args, 0), newstr)) {
3875 /* really not much we can do; just leak */
3876 PyErr_Clear();
3877 }
3878 else {
3879 Py_DECREF(newstr);
3880 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003881
3882#if defined(PYOS_OS2)
3883 }
3884#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003885 Py_INCREF(Py_None);
3886 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003887}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003888#endif /* putenv */
3889
3890#ifdef HAVE_STRERROR
3891static char posix_strerror__doc__[] =
3892"strerror(code) -> string\n\
3893Translate an error code to a message string.";
3894
Guido van Rossumf68d8e52001-04-14 17:55:09 +00003895static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003896posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003897{
3898 int code;
3899 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003900 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003901 return NULL;
3902 message = strerror(code);
3903 if (message == NULL) {
3904 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003905 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003906 return NULL;
3907 }
3908 return PyString_FromString(message);
3909}
3910#endif /* strerror */
3911
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003912
Guido van Rossumc9641791998-08-04 15:26:23 +00003913#ifdef HAVE_SYS_WAIT_H
3914
3915#ifdef WIFSTOPPED
3916static char posix_WIFSTOPPED__doc__[] =
3917"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003918Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003919
3920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003921posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003922{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003923#ifdef UNION_WAIT
3924 union wait status;
3925#define status_i (status.w_status)
3926#else
3927 int status;
3928#define status_i status
3929#endif
3930 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003931
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003932 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003933 {
3934 return NULL;
3935 }
3936
3937 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003938#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003939}
3940#endif /* WIFSTOPPED */
3941
3942#ifdef WIFSIGNALED
3943static char posix_WIFSIGNALED__doc__[] =
3944"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003945Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003946
3947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003948posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003949{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003950#ifdef UNION_WAIT
3951 union wait status;
3952#define status_i (status.w_status)
3953#else
3954 int status;
3955#define status_i status
3956#endif
3957 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003958
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003959 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003960 {
3961 return NULL;
3962 }
3963
3964 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003965#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003966}
3967#endif /* WIFSIGNALED */
3968
3969#ifdef WIFEXITED
3970static char posix_WIFEXITED__doc__[] =
3971"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003972Return true if the process returning 'status' exited using the exit()\n\
3973system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003974
3975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003976posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003977{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003978#ifdef UNION_WAIT
3979 union wait status;
3980#define status_i (status.w_status)
3981#else
3982 int status;
3983#define status_i status
3984#endif
3985 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003986
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003987 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003988 {
3989 return NULL;
3990 }
3991
3992 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003993#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003994}
3995#endif /* WIFEXITED */
3996
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003997#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003998static char posix_WEXITSTATUS__doc__[] =
3999"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004000Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004001
4002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004003posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004004{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004005#ifdef UNION_WAIT
4006 union wait status;
4007#define status_i (status.w_status)
4008#else
4009 int status;
4010#define status_i status
4011#endif
4012 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004013
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004014 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004015 {
4016 return NULL;
4017 }
4018
4019 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004020#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004021}
4022#endif /* WEXITSTATUS */
4023
4024#ifdef WTERMSIG
4025static char posix_WTERMSIG__doc__[] =
4026"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004027Return the signal that terminated the process that provided the 'status'\n\
4028value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004029
4030static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004031posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004032{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004033#ifdef UNION_WAIT
4034 union wait status;
4035#define status_i (status.w_status)
4036#else
4037 int status;
4038#define status_i status
4039#endif
4040 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004041
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004042 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004043 {
4044 return NULL;
4045 }
4046
4047 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004048#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004049}
4050#endif /* WTERMSIG */
4051
4052#ifdef WSTOPSIG
4053static char posix_WSTOPSIG__doc__[] =
4054"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004055Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004056
4057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004058posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004059{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004060#ifdef UNION_WAIT
4061 union wait status;
4062#define status_i (status.w_status)
4063#else
4064 int status;
4065#define status_i status
4066#endif
4067 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004068
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004069 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004070 {
4071 return NULL;
4072 }
4073
4074 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004075#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004076}
4077#endif /* WSTOPSIG */
4078
4079#endif /* HAVE_SYS_WAIT_H */
4080
4081
Guido van Rossum94f6f721999-01-06 18:42:14 +00004082#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004083#ifdef _SCO_DS
4084/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4085 needed definitions in sys/statvfs.h */
4086#define _SVID3
4087#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004088#include <sys/statvfs.h>
4089
4090static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004091"fstatvfs(fd) -> \n\
4092 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004093Perform an fstatvfs system call on the given fd.";
4094
4095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004096posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004097{
4098 int fd, res;
4099 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004100 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004101 return NULL;
4102 Py_BEGIN_ALLOW_THREADS
4103 res = fstatvfs(fd, &st);
4104 Py_END_ALLOW_THREADS
4105 if (res != 0)
4106 return posix_error();
4107#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004108 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004109 (long) st.f_bsize,
4110 (long) st.f_frsize,
4111 (long) st.f_blocks,
4112 (long) st.f_bfree,
4113 (long) st.f_bavail,
4114 (long) st.f_files,
4115 (long) st.f_ffree,
4116 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004117 (long) st.f_flag,
4118 (long) st.f_namemax);
4119#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004120 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004121 (long) st.f_bsize,
4122 (long) st.f_frsize,
4123 (LONG_LONG) st.f_blocks,
4124 (LONG_LONG) st.f_bfree,
4125 (LONG_LONG) st.f_bavail,
4126 (LONG_LONG) st.f_files,
4127 (LONG_LONG) st.f_ffree,
4128 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004129 (long) st.f_flag,
4130 (long) st.f_namemax);
4131#endif
4132}
4133#endif /* HAVE_FSTATVFS */
4134
4135
4136#if defined(HAVE_STATVFS)
4137#include <sys/statvfs.h>
4138
4139static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004140"statvfs(path) -> \n\
4141 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004142Perform a statvfs system call on the given path.";
4143
4144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004145posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004146{
4147 char *path;
4148 int res;
4149 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004150 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004151 return NULL;
4152 Py_BEGIN_ALLOW_THREADS
4153 res = statvfs(path, &st);
4154 Py_END_ALLOW_THREADS
4155 if (res != 0)
4156 return posix_error_with_filename(path);
4157#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004158 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004159 (long) st.f_bsize,
4160 (long) st.f_frsize,
4161 (long) st.f_blocks,
4162 (long) st.f_bfree,
4163 (long) st.f_bavail,
4164 (long) st.f_files,
4165 (long) st.f_ffree,
4166 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004167 (long) st.f_flag,
4168 (long) st.f_namemax);
4169#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004170 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004171 (long) st.f_bsize,
4172 (long) st.f_frsize,
4173 (LONG_LONG) st.f_blocks,
4174 (LONG_LONG) st.f_bfree,
4175 (LONG_LONG) st.f_bavail,
4176 (LONG_LONG) st.f_files,
4177 (LONG_LONG) st.f_ffree,
4178 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004179 (long) st.f_flag,
4180 (long) st.f_namemax);
4181#endif
4182}
4183#endif /* HAVE_STATVFS */
4184
4185
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004186#ifdef HAVE_TEMPNAM
4187static char posix_tempnam__doc__[] = "\
4188tempnam([dir[, prefix]]) -> string\n\
4189Return a unique name for a temporary file.\n\
4190The directory and a short may be specified as strings; they may be omitted\n\
4191or None if not needed.";
4192
4193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004194posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004195{
4196 PyObject *result = NULL;
4197 char *dir = NULL;
4198 char *pfx = NULL;
4199 char *name;
4200
4201 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4202 return NULL;
4203 name = tempnam(dir, pfx);
4204 if (name == NULL)
4205 return PyErr_NoMemory();
4206 result = PyString_FromString(name);
4207 free(name);
4208 return result;
4209}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004210#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004211
4212
4213#ifdef HAVE_TMPFILE
4214static char posix_tmpfile__doc__[] = "\
4215tmpfile() -> file object\n\
4216Create a temporary file with no directory entries.";
4217
4218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004219posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004220{
4221 FILE *fp;
4222
4223 if (!PyArg_ParseTuple(args, ":tmpfile"))
4224 return NULL;
4225 fp = tmpfile();
4226 if (fp == NULL)
4227 return posix_error();
4228 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4229}
4230#endif
4231
4232
4233#ifdef HAVE_TMPNAM
4234static char posix_tmpnam__doc__[] = "\
4235tmpnam() -> string\n\
4236Return a unique name for a temporary file.";
4237
4238static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004239posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004240{
4241 char buffer[L_tmpnam];
4242 char *name;
4243
4244 if (!PyArg_ParseTuple(args, ":tmpnam"))
4245 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004246#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004247 name = tmpnam_r(buffer);
4248#else
4249 name = tmpnam(buffer);
4250#endif
4251 if (name == NULL) {
4252 PyErr_SetObject(PyExc_OSError,
4253 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004254#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004255 "unexpected NULL from tmpnam_r"
4256#else
4257 "unexpected NULL from tmpnam"
4258#endif
4259 ));
4260 return NULL;
4261 }
4262 return PyString_FromString(buffer);
4263}
4264#endif
4265
4266
Fred Drakec9680921999-12-13 16:37:25 +00004267/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4268 * It maps strings representing configuration variable names to
4269 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004270 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004271 * rarely-used constants. There are three separate tables that use
4272 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004273 *
4274 * This code is always included, even if none of the interfaces that
4275 * need it are included. The #if hackery needed to avoid it would be
4276 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004277 */
4278struct constdef {
4279 char *name;
4280 long value;
4281};
4282
Fred Drake12c6e2d1999-12-14 21:25:03 +00004283static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004284conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4285 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004286{
4287 if (PyInt_Check(arg)) {
4288 *valuep = PyInt_AS_LONG(arg);
4289 return 1;
4290 }
4291 if (PyString_Check(arg)) {
4292 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004293 size_t lo = 0;
4294 size_t mid;
4295 size_t hi = tablesize;
4296 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004297 char *confname = PyString_AS_STRING(arg);
4298 while (lo < hi) {
4299 mid = (lo + hi) / 2;
4300 cmp = strcmp(confname, table[mid].name);
4301 if (cmp < 0)
4302 hi = mid;
4303 else if (cmp > 0)
4304 lo = mid + 1;
4305 else {
4306 *valuep = table[mid].value;
4307 return 1;
4308 }
4309 }
4310 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4311 }
4312 else
4313 PyErr_SetString(PyExc_TypeError,
4314 "configuration names must be strings or integers");
4315 return 0;
4316}
4317
4318
4319#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4320static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004321#ifdef _PC_ABI_AIO_XFER_MAX
4322 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4323#endif
4324#ifdef _PC_ABI_ASYNC_IO
4325 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4326#endif
Fred Drakec9680921999-12-13 16:37:25 +00004327#ifdef _PC_ASYNC_IO
4328 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4329#endif
4330#ifdef _PC_CHOWN_RESTRICTED
4331 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4332#endif
4333#ifdef _PC_FILESIZEBITS
4334 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4335#endif
4336#ifdef _PC_LAST
4337 {"PC_LAST", _PC_LAST},
4338#endif
4339#ifdef _PC_LINK_MAX
4340 {"PC_LINK_MAX", _PC_LINK_MAX},
4341#endif
4342#ifdef _PC_MAX_CANON
4343 {"PC_MAX_CANON", _PC_MAX_CANON},
4344#endif
4345#ifdef _PC_MAX_INPUT
4346 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4347#endif
4348#ifdef _PC_NAME_MAX
4349 {"PC_NAME_MAX", _PC_NAME_MAX},
4350#endif
4351#ifdef _PC_NO_TRUNC
4352 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4353#endif
4354#ifdef _PC_PATH_MAX
4355 {"PC_PATH_MAX", _PC_PATH_MAX},
4356#endif
4357#ifdef _PC_PIPE_BUF
4358 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4359#endif
4360#ifdef _PC_PRIO_IO
4361 {"PC_PRIO_IO", _PC_PRIO_IO},
4362#endif
4363#ifdef _PC_SOCK_MAXBUF
4364 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4365#endif
4366#ifdef _PC_SYNC_IO
4367 {"PC_SYNC_IO", _PC_SYNC_IO},
4368#endif
4369#ifdef _PC_VDISABLE
4370 {"PC_VDISABLE", _PC_VDISABLE},
4371#endif
4372};
4373
Fred Drakec9680921999-12-13 16:37:25 +00004374static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004375conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004376{
4377 return conv_confname(arg, valuep, posix_constants_pathconf,
4378 sizeof(posix_constants_pathconf)
4379 / sizeof(struct constdef));
4380}
4381#endif
4382
4383#ifdef HAVE_FPATHCONF
4384static char posix_fpathconf__doc__[] = "\
4385fpathconf(fd, name) -> integer\n\
4386Return the configuration limit name for the file descriptor fd.\n\
4387If there is no limit, return -1.";
4388
4389static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004390posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004391{
4392 PyObject *result = NULL;
4393 int name, fd;
4394
Fred Drake12c6e2d1999-12-14 21:25:03 +00004395 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4396 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004397 long limit;
4398
4399 errno = 0;
4400 limit = fpathconf(fd, name);
4401 if (limit == -1 && errno != 0)
4402 posix_error();
4403 else
4404 result = PyInt_FromLong(limit);
4405 }
4406 return result;
4407}
4408#endif
4409
4410
4411#ifdef HAVE_PATHCONF
4412static char posix_pathconf__doc__[] = "\
4413pathconf(path, name) -> integer\n\
4414Return the configuration limit name for the file or directory path.\n\
4415If there is no limit, return -1.";
4416
4417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004418posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004419{
4420 PyObject *result = NULL;
4421 int name;
4422 char *path;
4423
4424 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4425 conv_path_confname, &name)) {
4426 long limit;
4427
4428 errno = 0;
4429 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004430 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004431 if (errno == EINVAL)
4432 /* could be a path or name problem */
4433 posix_error();
4434 else
4435 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004436 }
Fred Drakec9680921999-12-13 16:37:25 +00004437 else
4438 result = PyInt_FromLong(limit);
4439 }
4440 return result;
4441}
4442#endif
4443
4444#ifdef HAVE_CONFSTR
4445static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004446#ifdef _CS_ARCHITECTURE
4447 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4448#endif
4449#ifdef _CS_HOSTNAME
4450 {"CS_HOSTNAME", _CS_HOSTNAME},
4451#endif
4452#ifdef _CS_HW_PROVIDER
4453 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4454#endif
4455#ifdef _CS_HW_SERIAL
4456 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4457#endif
4458#ifdef _CS_INITTAB_NAME
4459 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4460#endif
Fred Drakec9680921999-12-13 16:37:25 +00004461#ifdef _CS_LFS64_CFLAGS
4462 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4463#endif
4464#ifdef _CS_LFS64_LDFLAGS
4465 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4466#endif
4467#ifdef _CS_LFS64_LIBS
4468 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4469#endif
4470#ifdef _CS_LFS64_LINTFLAGS
4471 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4472#endif
4473#ifdef _CS_LFS_CFLAGS
4474 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4475#endif
4476#ifdef _CS_LFS_LDFLAGS
4477 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4478#endif
4479#ifdef _CS_LFS_LIBS
4480 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4481#endif
4482#ifdef _CS_LFS_LINTFLAGS
4483 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4484#endif
Fred Draked86ed291999-12-15 15:34:33 +00004485#ifdef _CS_MACHINE
4486 {"CS_MACHINE", _CS_MACHINE},
4487#endif
Fred Drakec9680921999-12-13 16:37:25 +00004488#ifdef _CS_PATH
4489 {"CS_PATH", _CS_PATH},
4490#endif
Fred Draked86ed291999-12-15 15:34:33 +00004491#ifdef _CS_RELEASE
4492 {"CS_RELEASE", _CS_RELEASE},
4493#endif
4494#ifdef _CS_SRPC_DOMAIN
4495 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4496#endif
4497#ifdef _CS_SYSNAME
4498 {"CS_SYSNAME", _CS_SYSNAME},
4499#endif
4500#ifdef _CS_VERSION
4501 {"CS_VERSION", _CS_VERSION},
4502#endif
Fred Drakec9680921999-12-13 16:37:25 +00004503#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4504 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4505#endif
4506#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4507 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4508#endif
4509#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4510 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4511#endif
4512#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4513 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4514#endif
4515#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4516 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4517#endif
4518#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4519 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4520#endif
4521#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4522 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4523#endif
4524#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4525 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4526#endif
4527#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4528 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4529#endif
4530#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4531 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4532#endif
4533#ifdef _CS_XBS5_LP64_OFF64_LIBS
4534 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4535#endif
4536#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4537 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4538#endif
4539#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4540 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4541#endif
4542#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4543 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4544#endif
4545#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4546 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4547#endif
4548#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4549 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4550#endif
Fred Draked86ed291999-12-15 15:34:33 +00004551#ifdef _MIPS_CS_AVAIL_PROCESSORS
4552 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4553#endif
4554#ifdef _MIPS_CS_BASE
4555 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4556#endif
4557#ifdef _MIPS_CS_HOSTID
4558 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4559#endif
4560#ifdef _MIPS_CS_HW_NAME
4561 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4562#endif
4563#ifdef _MIPS_CS_NUM_PROCESSORS
4564 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4565#endif
4566#ifdef _MIPS_CS_OSREL_MAJ
4567 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4568#endif
4569#ifdef _MIPS_CS_OSREL_MIN
4570 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4571#endif
4572#ifdef _MIPS_CS_OSREL_PATCH
4573 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4574#endif
4575#ifdef _MIPS_CS_OS_NAME
4576 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4577#endif
4578#ifdef _MIPS_CS_OS_PROVIDER
4579 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4580#endif
4581#ifdef _MIPS_CS_PROCESSORS
4582 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4583#endif
4584#ifdef _MIPS_CS_SERIAL
4585 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4586#endif
4587#ifdef _MIPS_CS_VENDOR
4588 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4589#endif
Fred Drakec9680921999-12-13 16:37:25 +00004590};
4591
4592static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004593conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004594{
4595 return conv_confname(arg, valuep, posix_constants_confstr,
4596 sizeof(posix_constants_confstr)
4597 / sizeof(struct constdef));
4598}
4599
4600static char posix_confstr__doc__[] = "\
4601confstr(name) -> string\n\
4602Return a string-valued system configuration variable.";
4603
4604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004605posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004606{
4607 PyObject *result = NULL;
4608 int name;
4609 char buffer[64];
4610
4611 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4612 int len = confstr(name, buffer, sizeof(buffer));
4613
Fred Drakec9680921999-12-13 16:37:25 +00004614 errno = 0;
4615 if (len == 0) {
4616 if (errno != 0)
4617 posix_error();
4618 else
4619 result = PyString_FromString("");
4620 }
4621 else {
4622 if (len >= sizeof(buffer)) {
4623 result = PyString_FromStringAndSize(NULL, len);
4624 if (result != NULL)
4625 confstr(name, PyString_AS_STRING(result), len+1);
4626 }
4627 else
4628 result = PyString_FromString(buffer);
4629 }
4630 }
4631 return result;
4632}
4633#endif
4634
4635
4636#ifdef HAVE_SYSCONF
4637static struct constdef posix_constants_sysconf[] = {
4638#ifdef _SC_2_CHAR_TERM
4639 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4640#endif
4641#ifdef _SC_2_C_BIND
4642 {"SC_2_C_BIND", _SC_2_C_BIND},
4643#endif
4644#ifdef _SC_2_C_DEV
4645 {"SC_2_C_DEV", _SC_2_C_DEV},
4646#endif
4647#ifdef _SC_2_C_VERSION
4648 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4649#endif
4650#ifdef _SC_2_FORT_DEV
4651 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4652#endif
4653#ifdef _SC_2_FORT_RUN
4654 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4655#endif
4656#ifdef _SC_2_LOCALEDEF
4657 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4658#endif
4659#ifdef _SC_2_SW_DEV
4660 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4661#endif
4662#ifdef _SC_2_UPE
4663 {"SC_2_UPE", _SC_2_UPE},
4664#endif
4665#ifdef _SC_2_VERSION
4666 {"SC_2_VERSION", _SC_2_VERSION},
4667#endif
Fred Draked86ed291999-12-15 15:34:33 +00004668#ifdef _SC_ABI_ASYNCHRONOUS_IO
4669 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4670#endif
4671#ifdef _SC_ACL
4672 {"SC_ACL", _SC_ACL},
4673#endif
Fred Drakec9680921999-12-13 16:37:25 +00004674#ifdef _SC_AIO_LISTIO_MAX
4675 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4676#endif
Fred Drakec9680921999-12-13 16:37:25 +00004677#ifdef _SC_AIO_MAX
4678 {"SC_AIO_MAX", _SC_AIO_MAX},
4679#endif
4680#ifdef _SC_AIO_PRIO_DELTA_MAX
4681 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4682#endif
4683#ifdef _SC_ARG_MAX
4684 {"SC_ARG_MAX", _SC_ARG_MAX},
4685#endif
4686#ifdef _SC_ASYNCHRONOUS_IO
4687 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4688#endif
4689#ifdef _SC_ATEXIT_MAX
4690 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4691#endif
Fred Draked86ed291999-12-15 15:34:33 +00004692#ifdef _SC_AUDIT
4693 {"SC_AUDIT", _SC_AUDIT},
4694#endif
Fred Drakec9680921999-12-13 16:37:25 +00004695#ifdef _SC_AVPHYS_PAGES
4696 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4697#endif
4698#ifdef _SC_BC_BASE_MAX
4699 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4700#endif
4701#ifdef _SC_BC_DIM_MAX
4702 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4703#endif
4704#ifdef _SC_BC_SCALE_MAX
4705 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4706#endif
4707#ifdef _SC_BC_STRING_MAX
4708 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4709#endif
Fred Draked86ed291999-12-15 15:34:33 +00004710#ifdef _SC_CAP
4711 {"SC_CAP", _SC_CAP},
4712#endif
Fred Drakec9680921999-12-13 16:37:25 +00004713#ifdef _SC_CHARCLASS_NAME_MAX
4714 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4715#endif
4716#ifdef _SC_CHAR_BIT
4717 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4718#endif
4719#ifdef _SC_CHAR_MAX
4720 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4721#endif
4722#ifdef _SC_CHAR_MIN
4723 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4724#endif
4725#ifdef _SC_CHILD_MAX
4726 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4727#endif
4728#ifdef _SC_CLK_TCK
4729 {"SC_CLK_TCK", _SC_CLK_TCK},
4730#endif
4731#ifdef _SC_COHER_BLKSZ
4732 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4733#endif
4734#ifdef _SC_COLL_WEIGHTS_MAX
4735 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4736#endif
4737#ifdef _SC_DCACHE_ASSOC
4738 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4739#endif
4740#ifdef _SC_DCACHE_BLKSZ
4741 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4742#endif
4743#ifdef _SC_DCACHE_LINESZ
4744 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4745#endif
4746#ifdef _SC_DCACHE_SZ
4747 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4748#endif
4749#ifdef _SC_DCACHE_TBLKSZ
4750 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4751#endif
4752#ifdef _SC_DELAYTIMER_MAX
4753 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4754#endif
4755#ifdef _SC_EQUIV_CLASS_MAX
4756 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4757#endif
4758#ifdef _SC_EXPR_NEST_MAX
4759 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4760#endif
4761#ifdef _SC_FSYNC
4762 {"SC_FSYNC", _SC_FSYNC},
4763#endif
4764#ifdef _SC_GETGR_R_SIZE_MAX
4765 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4766#endif
4767#ifdef _SC_GETPW_R_SIZE_MAX
4768 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4769#endif
4770#ifdef _SC_ICACHE_ASSOC
4771 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4772#endif
4773#ifdef _SC_ICACHE_BLKSZ
4774 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4775#endif
4776#ifdef _SC_ICACHE_LINESZ
4777 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4778#endif
4779#ifdef _SC_ICACHE_SZ
4780 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4781#endif
Fred Draked86ed291999-12-15 15:34:33 +00004782#ifdef _SC_INF
4783 {"SC_INF", _SC_INF},
4784#endif
Fred Drakec9680921999-12-13 16:37:25 +00004785#ifdef _SC_INT_MAX
4786 {"SC_INT_MAX", _SC_INT_MAX},
4787#endif
4788#ifdef _SC_INT_MIN
4789 {"SC_INT_MIN", _SC_INT_MIN},
4790#endif
4791#ifdef _SC_IOV_MAX
4792 {"SC_IOV_MAX", _SC_IOV_MAX},
4793#endif
Fred Draked86ed291999-12-15 15:34:33 +00004794#ifdef _SC_IP_SECOPTS
4795 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4796#endif
Fred Drakec9680921999-12-13 16:37:25 +00004797#ifdef _SC_JOB_CONTROL
4798 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4799#endif
Fred Draked86ed291999-12-15 15:34:33 +00004800#ifdef _SC_KERN_POINTERS
4801 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4802#endif
4803#ifdef _SC_KERN_SIM
4804 {"SC_KERN_SIM", _SC_KERN_SIM},
4805#endif
Fred Drakec9680921999-12-13 16:37:25 +00004806#ifdef _SC_LINE_MAX
4807 {"SC_LINE_MAX", _SC_LINE_MAX},
4808#endif
4809#ifdef _SC_LOGIN_NAME_MAX
4810 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4811#endif
4812#ifdef _SC_LOGNAME_MAX
4813 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4814#endif
4815#ifdef _SC_LONG_BIT
4816 {"SC_LONG_BIT", _SC_LONG_BIT},
4817#endif
Fred Draked86ed291999-12-15 15:34:33 +00004818#ifdef _SC_MAC
4819 {"SC_MAC", _SC_MAC},
4820#endif
Fred Drakec9680921999-12-13 16:37:25 +00004821#ifdef _SC_MAPPED_FILES
4822 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4823#endif
4824#ifdef _SC_MAXPID
4825 {"SC_MAXPID", _SC_MAXPID},
4826#endif
4827#ifdef _SC_MB_LEN_MAX
4828 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4829#endif
4830#ifdef _SC_MEMLOCK
4831 {"SC_MEMLOCK", _SC_MEMLOCK},
4832#endif
4833#ifdef _SC_MEMLOCK_RANGE
4834 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4835#endif
4836#ifdef _SC_MEMORY_PROTECTION
4837 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4838#endif
4839#ifdef _SC_MESSAGE_PASSING
4840 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4841#endif
Fred Draked86ed291999-12-15 15:34:33 +00004842#ifdef _SC_MMAP_FIXED_ALIGNMENT
4843 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4844#endif
Fred Drakec9680921999-12-13 16:37:25 +00004845#ifdef _SC_MQ_OPEN_MAX
4846 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4847#endif
4848#ifdef _SC_MQ_PRIO_MAX
4849 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4850#endif
Fred Draked86ed291999-12-15 15:34:33 +00004851#ifdef _SC_NACLS_MAX
4852 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4853#endif
Fred Drakec9680921999-12-13 16:37:25 +00004854#ifdef _SC_NGROUPS_MAX
4855 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4856#endif
4857#ifdef _SC_NL_ARGMAX
4858 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4859#endif
4860#ifdef _SC_NL_LANGMAX
4861 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4862#endif
4863#ifdef _SC_NL_MSGMAX
4864 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4865#endif
4866#ifdef _SC_NL_NMAX
4867 {"SC_NL_NMAX", _SC_NL_NMAX},
4868#endif
4869#ifdef _SC_NL_SETMAX
4870 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4871#endif
4872#ifdef _SC_NL_TEXTMAX
4873 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4874#endif
4875#ifdef _SC_NPROCESSORS_CONF
4876 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4877#endif
4878#ifdef _SC_NPROCESSORS_ONLN
4879 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4880#endif
Fred Draked86ed291999-12-15 15:34:33 +00004881#ifdef _SC_NPROC_CONF
4882 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4883#endif
4884#ifdef _SC_NPROC_ONLN
4885 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4886#endif
Fred Drakec9680921999-12-13 16:37:25 +00004887#ifdef _SC_NZERO
4888 {"SC_NZERO", _SC_NZERO},
4889#endif
4890#ifdef _SC_OPEN_MAX
4891 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4892#endif
4893#ifdef _SC_PAGESIZE
4894 {"SC_PAGESIZE", _SC_PAGESIZE},
4895#endif
4896#ifdef _SC_PAGE_SIZE
4897 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4898#endif
4899#ifdef _SC_PASS_MAX
4900 {"SC_PASS_MAX", _SC_PASS_MAX},
4901#endif
4902#ifdef _SC_PHYS_PAGES
4903 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4904#endif
4905#ifdef _SC_PII
4906 {"SC_PII", _SC_PII},
4907#endif
4908#ifdef _SC_PII_INTERNET
4909 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4910#endif
4911#ifdef _SC_PII_INTERNET_DGRAM
4912 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4913#endif
4914#ifdef _SC_PII_INTERNET_STREAM
4915 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4916#endif
4917#ifdef _SC_PII_OSI
4918 {"SC_PII_OSI", _SC_PII_OSI},
4919#endif
4920#ifdef _SC_PII_OSI_CLTS
4921 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4922#endif
4923#ifdef _SC_PII_OSI_COTS
4924 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4925#endif
4926#ifdef _SC_PII_OSI_M
4927 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4928#endif
4929#ifdef _SC_PII_SOCKET
4930 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4931#endif
4932#ifdef _SC_PII_XTI
4933 {"SC_PII_XTI", _SC_PII_XTI},
4934#endif
4935#ifdef _SC_POLL
4936 {"SC_POLL", _SC_POLL},
4937#endif
4938#ifdef _SC_PRIORITIZED_IO
4939 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4940#endif
4941#ifdef _SC_PRIORITY_SCHEDULING
4942 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4943#endif
4944#ifdef _SC_REALTIME_SIGNALS
4945 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4946#endif
4947#ifdef _SC_RE_DUP_MAX
4948 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4949#endif
4950#ifdef _SC_RTSIG_MAX
4951 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4952#endif
4953#ifdef _SC_SAVED_IDS
4954 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4955#endif
4956#ifdef _SC_SCHAR_MAX
4957 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4958#endif
4959#ifdef _SC_SCHAR_MIN
4960 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4961#endif
4962#ifdef _SC_SELECT
4963 {"SC_SELECT", _SC_SELECT},
4964#endif
4965#ifdef _SC_SEMAPHORES
4966 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4967#endif
4968#ifdef _SC_SEM_NSEMS_MAX
4969 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4970#endif
4971#ifdef _SC_SEM_VALUE_MAX
4972 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4973#endif
4974#ifdef _SC_SHARED_MEMORY_OBJECTS
4975 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4976#endif
4977#ifdef _SC_SHRT_MAX
4978 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4979#endif
4980#ifdef _SC_SHRT_MIN
4981 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4982#endif
4983#ifdef _SC_SIGQUEUE_MAX
4984 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4985#endif
4986#ifdef _SC_SIGRT_MAX
4987 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4988#endif
4989#ifdef _SC_SIGRT_MIN
4990 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4991#endif
Fred Draked86ed291999-12-15 15:34:33 +00004992#ifdef _SC_SOFTPOWER
4993 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4994#endif
Fred Drakec9680921999-12-13 16:37:25 +00004995#ifdef _SC_SPLIT_CACHE
4996 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4997#endif
4998#ifdef _SC_SSIZE_MAX
4999 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5000#endif
5001#ifdef _SC_STACK_PROT
5002 {"SC_STACK_PROT", _SC_STACK_PROT},
5003#endif
5004#ifdef _SC_STREAM_MAX
5005 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5006#endif
5007#ifdef _SC_SYNCHRONIZED_IO
5008 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5009#endif
5010#ifdef _SC_THREADS
5011 {"SC_THREADS", _SC_THREADS},
5012#endif
5013#ifdef _SC_THREAD_ATTR_STACKADDR
5014 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5015#endif
5016#ifdef _SC_THREAD_ATTR_STACKSIZE
5017 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5018#endif
5019#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5020 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5021#endif
5022#ifdef _SC_THREAD_KEYS_MAX
5023 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5024#endif
5025#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5026 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5027#endif
5028#ifdef _SC_THREAD_PRIO_INHERIT
5029 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5030#endif
5031#ifdef _SC_THREAD_PRIO_PROTECT
5032 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5033#endif
5034#ifdef _SC_THREAD_PROCESS_SHARED
5035 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5036#endif
5037#ifdef _SC_THREAD_SAFE_FUNCTIONS
5038 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5039#endif
5040#ifdef _SC_THREAD_STACK_MIN
5041 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5042#endif
5043#ifdef _SC_THREAD_THREADS_MAX
5044 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5045#endif
5046#ifdef _SC_TIMERS
5047 {"SC_TIMERS", _SC_TIMERS},
5048#endif
5049#ifdef _SC_TIMER_MAX
5050 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5051#endif
5052#ifdef _SC_TTY_NAME_MAX
5053 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5054#endif
5055#ifdef _SC_TZNAME_MAX
5056 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5057#endif
5058#ifdef _SC_T_IOV_MAX
5059 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5060#endif
5061#ifdef _SC_UCHAR_MAX
5062 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5063#endif
5064#ifdef _SC_UINT_MAX
5065 {"SC_UINT_MAX", _SC_UINT_MAX},
5066#endif
5067#ifdef _SC_UIO_MAXIOV
5068 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5069#endif
5070#ifdef _SC_ULONG_MAX
5071 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5072#endif
5073#ifdef _SC_USHRT_MAX
5074 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5075#endif
5076#ifdef _SC_VERSION
5077 {"SC_VERSION", _SC_VERSION},
5078#endif
5079#ifdef _SC_WORD_BIT
5080 {"SC_WORD_BIT", _SC_WORD_BIT},
5081#endif
5082#ifdef _SC_XBS5_ILP32_OFF32
5083 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5084#endif
5085#ifdef _SC_XBS5_ILP32_OFFBIG
5086 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5087#endif
5088#ifdef _SC_XBS5_LP64_OFF64
5089 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5090#endif
5091#ifdef _SC_XBS5_LPBIG_OFFBIG
5092 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5093#endif
5094#ifdef _SC_XOPEN_CRYPT
5095 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5096#endif
5097#ifdef _SC_XOPEN_ENH_I18N
5098 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5099#endif
5100#ifdef _SC_XOPEN_LEGACY
5101 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5102#endif
5103#ifdef _SC_XOPEN_REALTIME
5104 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5105#endif
5106#ifdef _SC_XOPEN_REALTIME_THREADS
5107 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5108#endif
5109#ifdef _SC_XOPEN_SHM
5110 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5111#endif
5112#ifdef _SC_XOPEN_UNIX
5113 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5114#endif
5115#ifdef _SC_XOPEN_VERSION
5116 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5117#endif
5118#ifdef _SC_XOPEN_XCU_VERSION
5119 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5120#endif
5121#ifdef _SC_XOPEN_XPG2
5122 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5123#endif
5124#ifdef _SC_XOPEN_XPG3
5125 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5126#endif
5127#ifdef _SC_XOPEN_XPG4
5128 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5129#endif
5130};
5131
5132static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005133conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005134{
5135 return conv_confname(arg, valuep, posix_constants_sysconf,
5136 sizeof(posix_constants_sysconf)
5137 / sizeof(struct constdef));
5138}
5139
5140static char posix_sysconf__doc__[] = "\
5141sysconf(name) -> integer\n\
5142Return an integer-valued system configuration variable.";
5143
5144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005145posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005146{
5147 PyObject *result = NULL;
5148 int name;
5149
5150 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5151 int value;
5152
5153 errno = 0;
5154 value = sysconf(name);
5155 if (value == -1 && errno != 0)
5156 posix_error();
5157 else
5158 result = PyInt_FromLong(value);
5159 }
5160 return result;
5161}
5162#endif
5163
5164
Fred Drakebec628d1999-12-15 18:31:10 +00005165/* This code is used to ensure that the tables of configuration value names
5166 * are in sorted order as required by conv_confname(), and also to build the
5167 * the exported dictionaries that are used to publish information about the
5168 * names available on the host platform.
5169 *
5170 * Sorting the table at runtime ensures that the table is properly ordered
5171 * when used, even for platforms we're not able to test on. It also makes
5172 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005173 */
Fred Drakebec628d1999-12-15 18:31:10 +00005174
5175static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005176cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005177{
5178 const struct constdef *c1 =
5179 (const struct constdef *) v1;
5180 const struct constdef *c2 =
5181 (const struct constdef *) v2;
5182
5183 return strcmp(c1->name, c2->name);
5184}
5185
5186static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005187setup_confname_table(struct constdef *table, size_t tablesize,
5188 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005189{
Fred Drakebec628d1999-12-15 18:31:10 +00005190 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005191 size_t i;
5192 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005193
5194 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5195 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005196 if (d == NULL)
5197 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005198
Barry Warsaw3155db32000-04-13 15:20:40 +00005199 for (i=0; i < tablesize; ++i) {
5200 PyObject *o = PyInt_FromLong(table[i].value);
5201 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5202 Py_XDECREF(o);
5203 Py_DECREF(d);
5204 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005205 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005206 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005207 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005208 status = PyDict_SetItemString(moddict, tablename, d);
5209 Py_DECREF(d);
5210 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005211}
5212
Fred Drakebec628d1999-12-15 18:31:10 +00005213/* Return -1 on failure, 0 on success. */
5214static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005215setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005216{
5217#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005218 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005219 sizeof(posix_constants_pathconf)
5220 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005221 "pathconf_names", moddict))
5222 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005223#endif
5224#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005225 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005226 sizeof(posix_constants_confstr)
5227 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005228 "confstr_names", moddict))
5229 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005230#endif
5231#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005232 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005233 sizeof(posix_constants_sysconf)
5234 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005235 "sysconf_names", moddict))
5236 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005237#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005238 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005239}
Fred Draked86ed291999-12-15 15:34:33 +00005240
5241
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005242static char posix_abort__doc__[] = "\
5243abort() -> does not return!\n\
5244Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5245in the hardest way possible on the hosting operating system.";
5246
5247static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005248posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005249{
5250 if (!PyArg_ParseTuple(args, ":abort"))
5251 return NULL;
5252 abort();
5253 /*NOTREACHED*/
5254 Py_FatalError("abort() called from Python code didn't abort!");
5255 return NULL;
5256}
Fred Drakebec628d1999-12-15 18:31:10 +00005257
Tim Petersf58a7aa2000-09-22 10:05:54 +00005258#ifdef MS_WIN32
5259static char win32_startfile__doc__[] = "\
5260startfile(filepath) - Start a file with its associated application.\n\
5261\n\
5262This acts like double-clicking the file in Explorer, or giving the file\n\
5263name as an argument to the DOS \"start\" command: the file is opened\n\
5264with whatever application (if any) its extension is associated.\n\
5265\n\
5266startfile returns as soon as the associated application is launched.\n\
5267There is no option to wait for the application to close, and no way\n\
5268to retrieve the application's exit status.\n\
5269\n\
5270The filepath is relative to the current directory. If you want to use\n\
5271an absolute path, make sure the first character is not a slash (\"/\");\n\
5272the underlying Win32 ShellExecute function doesn't work if it is.";
5273
5274static PyObject *
5275win32_startfile(PyObject *self, PyObject *args)
5276{
5277 char *filepath;
5278 HINSTANCE rc;
5279 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5280 return NULL;
5281 Py_BEGIN_ALLOW_THREADS
5282 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5283 Py_END_ALLOW_THREADS
5284 if (rc <= (HINSTANCE)32)
5285 return win32_error("startfile", filepath);
5286 Py_INCREF(Py_None);
5287 return Py_None;
5288}
5289#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005290
5291static PyMethodDef posix_methods[] = {
5292 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5293#ifdef HAVE_TTYNAME
5294 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5295#endif
5296 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5297 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005298#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005299 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005300#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005301#ifdef HAVE_CTERMID
5302 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5303#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005304#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005305 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005306#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005307#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005308 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005309#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005310 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5311 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5312 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005313#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005314 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005315#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005316#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005317 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005318#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005319 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5320 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5321 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005322#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005323 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005324#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005325#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005326 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005327#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005328 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005329#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005330 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005331#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005332 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5333 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5334 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005335#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005336 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005337#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005338 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005339#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005340 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5341 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005342#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005343#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005344 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5345 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005346#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005347#ifdef HAVE_FORK1
5348 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5349#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005350#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005351 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005352#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005353#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005354 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005355#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005356#ifdef HAVE_FORKPTY
5357 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5358#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005359#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005360 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005361#endif /* HAVE_GETEGID */
5362#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005363 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005364#endif /* HAVE_GETEUID */
5365#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005366 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005367#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005368#ifdef HAVE_GETGROUPS
5369 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5370#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005371 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005372#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005373 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005374#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005375#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005376 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005377#endif /* HAVE_GETPPID */
5378#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005379 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005380#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005381#ifdef HAVE_GETLOGIN
5382 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5383#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005384#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005385 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005386#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005387#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005388 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005389#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005390#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005391 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005392#ifdef MS_WIN32
5393 {"popen2", win32_popen2, METH_VARARGS},
5394 {"popen3", win32_popen3, METH_VARARGS},
5395 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005396 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005397#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005398#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005399#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005400 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005401#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005402#ifdef HAVE_SETEUID
5403 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5404#endif /* HAVE_SETEUID */
5405#ifdef HAVE_SETEGID
5406 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5407#endif /* HAVE_SETEGID */
5408#ifdef HAVE_SETREUID
5409 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5410#endif /* HAVE_SETREUID */
5411#ifdef HAVE_SETREGID
5412 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5413#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005414#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005415 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005416#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005417#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005418 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005419#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005420#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005421 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005422#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005423#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005424 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005425#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005426#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005427 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005428#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005429#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005430 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005431#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005432#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005433 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005434#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005435#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005436 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005437#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005438 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5439 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5440 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5441 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5442 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5443 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5444 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5445 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5446 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005447 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005448#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005449 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005450#endif
5451#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005452 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005453#endif
5454#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005455 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005456#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005457#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005458 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005459#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005460#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005461 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005462#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005463#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005464 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005465#endif
5466#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005467 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005468#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005469#ifdef HAVE_SYS_WAIT_H
5470#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005471 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005472#endif /* WIFSTOPPED */
5473#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005474 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005475#endif /* WIFSIGNALED */
5476#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005477 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005478#endif /* WIFEXITED */
5479#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005480 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005481#endif /* WEXITSTATUS */
5482#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005483 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005484#endif /* WTERMSIG */
5485#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005486 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005487#endif /* WSTOPSIG */
5488#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005489#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005490 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005491#endif
5492#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005493 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005494#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005495#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005496 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5497#endif
5498#ifdef HAVE_TEMPNAM
5499 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5500#endif
5501#ifdef HAVE_TMPNAM
5502 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5503#endif
Fred Drakec9680921999-12-13 16:37:25 +00005504#ifdef HAVE_CONFSTR
5505 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5506#endif
5507#ifdef HAVE_SYSCONF
5508 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5509#endif
5510#ifdef HAVE_FPATHCONF
5511 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5512#endif
5513#ifdef HAVE_PATHCONF
5514 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5515#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005516 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005517#ifdef MS_WIN32
5518 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5519#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005520 {NULL, NULL} /* Sentinel */
5521};
5522
5523
Barry Warsaw4a342091996-12-19 23:50:02 +00005524static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005525ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005526{
5527 PyObject* v = PyInt_FromLong(value);
5528 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5529 return -1; /* triggers fatal error */
5530
5531 Py_DECREF(v);
5532 return 0;
5533}
5534
Guido van Rossumd48f2521997-12-05 22:19:34 +00005535#if defined(PYOS_OS2)
5536/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5537static int insertvalues(PyObject *d)
5538{
5539 APIRET rc;
5540 ULONG values[QSV_MAX+1];
5541 PyObject *v;
5542 char *ver, tmp[10];
5543
5544 Py_BEGIN_ALLOW_THREADS
5545 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5546 Py_END_ALLOW_THREADS
5547
5548 if (rc != NO_ERROR) {
5549 os2_error(rc);
5550 return -1;
5551 }
5552
5553 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5554 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5555 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5556 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5557 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5558 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5559 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5560
5561 switch (values[QSV_VERSION_MINOR]) {
5562 case 0: ver = "2.00"; break;
5563 case 10: ver = "2.10"; break;
5564 case 11: ver = "2.11"; break;
5565 case 30: ver = "3.00"; break;
5566 case 40: ver = "4.00"; break;
5567 case 50: ver = "5.00"; break;
5568 default:
5569 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5570 values[QSV_VERSION_MINOR]);
5571 ver = &tmp[0];
5572 }
5573
5574 /* Add Indicator of the Version of the Operating System */
5575 v = PyString_FromString(ver);
5576 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5577 return -1;
5578 Py_DECREF(v);
5579
5580 /* Add Indicator of Which Drive was Used to Boot the System */
5581 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5582 tmp[1] = ':';
5583 tmp[2] = '\0';
5584
5585 v = PyString_FromString(tmp);
5586 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5587 return -1;
5588 Py_DECREF(v);
5589
5590 return 0;
5591}
5592#endif
5593
Barry Warsaw4a342091996-12-19 23:50:02 +00005594static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005595all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005596{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005597#ifdef F_OK
5598 if (ins(d, "F_OK", (long)F_OK)) return -1;
5599#endif
5600#ifdef R_OK
5601 if (ins(d, "R_OK", (long)R_OK)) return -1;
5602#endif
5603#ifdef W_OK
5604 if (ins(d, "W_OK", (long)W_OK)) return -1;
5605#endif
5606#ifdef X_OK
5607 if (ins(d, "X_OK", (long)X_OK)) return -1;
5608#endif
Fred Drakec9680921999-12-13 16:37:25 +00005609#ifdef NGROUPS_MAX
5610 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5611#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005612#ifdef TMP_MAX
5613 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5614#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005615#ifdef WNOHANG
5616 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5617#endif
5618#ifdef O_RDONLY
5619 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5620#endif
5621#ifdef O_WRONLY
5622 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5623#endif
5624#ifdef O_RDWR
5625 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5626#endif
5627#ifdef O_NDELAY
5628 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5629#endif
5630#ifdef O_NONBLOCK
5631 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5632#endif
5633#ifdef O_APPEND
5634 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5635#endif
5636#ifdef O_DSYNC
5637 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5638#endif
5639#ifdef O_RSYNC
5640 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5641#endif
5642#ifdef O_SYNC
5643 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5644#endif
5645#ifdef O_NOCTTY
5646 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5647#endif
5648#ifdef O_CREAT
5649 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5650#endif
5651#ifdef O_EXCL
5652 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5653#endif
5654#ifdef O_TRUNC
5655 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5656#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005657#ifdef O_BINARY
5658 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5659#endif
5660#ifdef O_TEXT
5661 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5662#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005663
Guido van Rossum246bc171999-02-01 23:54:31 +00005664#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005665 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5666 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5667 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5668 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5669 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005670#endif
5671
Guido van Rossumd48f2521997-12-05 22:19:34 +00005672#if defined(PYOS_OS2)
5673 if (insertvalues(d)) return -1;
5674#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005675 return 0;
5676}
5677
5678
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005679#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005680#define INITFUNC initnt
5681#define MODNAME "nt"
5682#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005683#if defined(PYOS_OS2)
5684#define INITFUNC initos2
5685#define MODNAME "os2"
5686#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005687#define INITFUNC initposix
5688#define MODNAME "posix"
5689#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005690#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005691
Guido van Rossum3886bb61998-12-04 18:50:17 +00005692DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005693INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005694{
Barry Warsaw53699e91996-12-10 23:23:01 +00005695 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005696
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005697 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005698 posix_methods,
5699 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005700 (PyObject *)NULL,
5701 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005702 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005703
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005704 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005705 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005706 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005707 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005708 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005709
Barry Warsaw4a342091996-12-19 23:50:02 +00005710 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005711 return;
5712
Fred Drakebec628d1999-12-15 18:31:10 +00005713 if (setup_confname_tables(d))
5714 return;
5715
Barry Warsawca74da41999-02-09 19:31:45 +00005716 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005717
Guido van Rossumb3d39562000-01-31 18:41:26 +00005718#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005719 if (posix_putenv_garbage == NULL)
5720 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005721#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005722}