blob: 3a85798df75020447b3cb519e52fbf170a090119 [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +000066#define HAVE_OPENDIR 1
67#define HAVE_PIPE 1
68#define HAVE_POPEN 1
69#define HAVE_SYSTEM 1
70#define HAVE_WAIT 1
71#else
72#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000073#define HAVE_GETCWD 1
74#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000075#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000076#define HAVE_EXECV 1
77#define HAVE_PIPE 1
78#define HAVE_POPEN 1
79#define HAVE_SYSTEM 1
80#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000081#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#else /* all other compilers */
83/* Unix functions that the configure script doesn't check for */
84#define HAVE_EXECV 1
85#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000086#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
87#define HAVE_FORK1 1
88#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000089#define HAVE_GETCWD 1
90#define HAVE_GETEGID 1
91#define HAVE_GETEUID 1
92#define HAVE_GETGID 1
93#define HAVE_GETPPID 1
94#define HAVE_GETUID 1
95#define HAVE_KILL 1
96#define HAVE_OPENDIR 1
97#define HAVE_PIPE 1
98#define HAVE_POPEN 1
99#define HAVE_SYSTEM 1
100#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000101#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000102#endif /* _MSC_VER */
103#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000105#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000106
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000107#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000108
Guido van Rossumb6775db1994-08-01 11:34:53 +0000109#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000110#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000111#endif
112
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000113#if defined(sun) && !defined(__SVR4)
114/* SunOS 4.1.4 doesn't have prototypes for these: */
115extern int rename(const char *, const char *);
116extern int pclose(FILE *);
117extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000118extern int fsync(int);
119extern int lstat(const char *, struct stat *);
120extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000121#endif
122
Guido van Rossum36bc6801995-06-14 22:54:23 +0000123#ifdef NeXT
124/* NeXT's <unistd.h> and <utime.h> aren't worth much */
125#undef HAVE_UNISTD_H
126#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000127#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000128/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000129#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000130#endif
131
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000132#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000135#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000136#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000138#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000139extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#endif
142#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int chdir(char *);
144extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000145#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(const char *);
147extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000149#ifdef __BORLANDC__
150extern int chmod(const char *, int);
151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000153#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int chown(const char *, uid_t, gid_t);
155extern char *getcwd(char *, int);
156extern char *strerror(int);
157extern int link(const char *, const char *);
158extern int rename(const char *, const char *);
159extern int stat(const char *, struct stat *);
160extern int unlink(const char *);
161extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000164#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000167#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000169
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172#ifdef HAVE_UTIME_H
173#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000174#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000176#ifdef HAVE_SYS_UTIME_H
177#include <sys/utime.h>
178#define HAVE_UTIME_H /* pretend we do for the rest of this file */
179#endif /* HAVE_SYS_UTIME_H */
180
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181#ifdef HAVE_SYS_TIMES_H
182#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000183#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184
185#ifdef HAVE_SYS_PARAM_H
186#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000187#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000188
189#ifdef HAVE_SYS_UTSNAME_H
190#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000191#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192
193#ifndef MAXPATHLEN
194#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000195#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000197#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#define NAMLEN(dirent) strlen((dirent)->d_name)
200#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000201#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000202#include <direct.h>
203#define NAMLEN(dirent) strlen((dirent)->d_name)
204#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000207#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#endif
211#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000213#endif
214#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000216#endif
217#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000219#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220#include <direct.h>
221#include <io.h>
222#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000223#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000225#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000227#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#else /* 16-bit Windows */
229#include <dos.h>
230#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000231#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233
Guido van Rossumd48f2521997-12-05 22:19:34 +0000234#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000236#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000238#ifdef UNION_WAIT
239/* Emulate some macros on systems that have a union instead of macros */
240
241#ifndef WIFEXITED
242#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
243#endif
244
245#ifndef WEXITSTATUS
246#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
247#endif
248
249#ifndef WTERMSIG
250#define WTERMSIG(u_wait) ((u_wait).w_termsig)
251#endif
252
253#endif /* UNION_WAIT */
254
Greg Wardb48bc172000-03-01 21:51:56 +0000255/* Don't use the "_r" form if we don't need it (also, won't have a
256 prototype for it, at least on Solaris -- maybe others as well?). */
257#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
258#define USE_CTERMID_R
259#endif
260
261#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
262#define USE_TMPNAM_R
263#endif
264
Fred Drake699f3522000-06-29 21:12:41 +0000265/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000266#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000267#ifdef MS_WIN64
268# define STAT _stati64
269# define FSTAT _fstati64
270# define STRUCT_STAT struct _stati64
271#else
272# define STAT stat
273# define FSTAT fstat
274# define STRUCT_STAT struct stat
275#endif
276
277
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278/* Return a dictionary corresponding to the POSIX environment table */
279
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000280#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283
Barry Warsaw53699e91996-12-10 23:23:01 +0000284static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000285convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286{
Barry Warsaw53699e91996-12-10 23:23:01 +0000287 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000289 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 if (d == NULL)
291 return NULL;
292 if (environ == NULL)
293 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000294 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000296 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000297 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298 char *p = strchr(*e, '=');
299 if (p == NULL)
300 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000301 k = PyString_FromStringAndSize(*e, (int)(p-*e));
302 if (k == NULL) {
303 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000305 }
306 v = PyString_FromString(p+1);
307 if (v == NULL) {
308 PyErr_Clear();
309 Py_DECREF(k);
310 continue;
311 }
312 if (PyDict_GetItem(d, k) == NULL) {
313 if (PyDict_SetItem(d, k, v) != 0)
314 PyErr_Clear();
315 }
316 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000317 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000319#if defined(PYOS_OS2)
320 {
321 APIRET rc;
322 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
323
324 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000325 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000326 PyObject *v = PyString_FromString(buffer);
327 PyDict_SetItemString(d, "BEGINLIBPATH", v);
328 Py_DECREF(v);
329 }
330 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
331 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
332 PyObject *v = PyString_FromString(buffer);
333 PyDict_SetItemString(d, "ENDLIBPATH", v);
334 Py_DECREF(v);
335 }
336 }
337#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338 return d;
339}
340
341
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342/* Set a POSIX-specific error from errno, and return NULL */
343
Barry Warsawd58d7641998-07-23 16:14:40 +0000344static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000345posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000346{
Barry Warsawca74da41999-02-09 19:31:45 +0000347 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348}
Barry Warsawd58d7641998-07-23 16:14:40 +0000349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000350posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000351{
Barry Warsawca74da41999-02-09 19:31:45 +0000352 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000353}
354
Mark Hammondef8b6542001-05-13 08:04:26 +0000355static PyObject *
356posix_error_with_allocated_filename(char* name)
357{
358 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
359 PyMem_Free(name);
360 return rc;
361}
362
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000363#ifdef MS_WIN32
364static PyObject *
365win32_error(char* function, char* filename)
366{
Mark Hammond33a6da92000-08-15 00:46:38 +0000367 /* XXX We should pass the function name along in the future.
368 (_winreg.c also wants to pass the function name.)
369 This would however require an additional param to the
370 Windows error object, which is non-trivial.
371 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000372 errno = GetLastError();
373 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000374 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000375 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000376 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000377}
378#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379
Guido van Rossumd48f2521997-12-05 22:19:34 +0000380#if defined(PYOS_OS2)
381/**********************************************************************
382 * Helper Function to Trim and Format OS/2 Messages
383 **********************************************************************/
384 static void
385os2_formatmsg(char *msgbuf, int msglen, char *reason)
386{
387 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
388
389 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
390 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
391
392 while (lastc > msgbuf && isspace(*lastc))
393 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
394 }
395
396 /* Add Optional Reason Text */
397 if (reason) {
398 strcat(msgbuf, " : ");
399 strcat(msgbuf, reason);
400 }
401}
402
403/**********************************************************************
404 * Decode an OS/2 Operating System Error Code
405 *
406 * A convenience function to lookup an OS/2 error code and return a
407 * text message we can use to raise a Python exception.
408 *
409 * Notes:
410 * The messages for errors returned from the OS/2 kernel reside in
411 * the file OSO001.MSG in the \OS2 directory hierarchy.
412 *
413 **********************************************************************/
414 static char *
415os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
416{
417 APIRET rc;
418 ULONG msglen;
419
420 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
421 Py_BEGIN_ALLOW_THREADS
422 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
423 errorcode, "oso001.msg", &msglen);
424 Py_END_ALLOW_THREADS
425
426 if (rc == NO_ERROR)
427 os2_formatmsg(msgbuf, msglen, reason);
428 else
429 sprintf(msgbuf, "unknown OS error #%d", errorcode);
430
431 return msgbuf;
432}
433
434/* Set an OS/2-specific error and return NULL. OS/2 kernel
435 errors are not in a global variable e.g. 'errno' nor are
436 they congruent with posix error numbers. */
437
438static PyObject * os2_error(int code)
439{
440 char text[1024];
441 PyObject *v;
442
443 os2_strerror(text, sizeof(text), code, "");
444
445 v = Py_BuildValue("(is)", code, text);
446 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000447 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000448 Py_DECREF(v);
449 }
450 return NULL; /* Signal to Python that an Exception is Pending */
451}
452
453#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000454
455/* POSIX generic methods */
456
Barry Warsaw53699e91996-12-10 23:23:01 +0000457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000458posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000459{
460 int fd;
461 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000462 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000463 return NULL;
464 Py_BEGIN_ALLOW_THREADS
465 res = (*func)(fd);
466 Py_END_ALLOW_THREADS
467 if (res < 0)
468 return posix_error();
469 Py_INCREF(Py_None);
470 return Py_None;
471}
472
473
474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000475posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000476{
Mark Hammondef8b6542001-05-13 08:04:26 +0000477 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000478 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000479 if (!PyArg_ParseTuple(args, format,
480 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000482 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000483 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000484 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000486 return posix_error_with_allocated_filename(path1);
487 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000488 Py_INCREF(Py_None);
489 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000490}
491
Barry Warsaw53699e91996-12-10 23:23:01 +0000492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000493posix_2str(PyObject *args, char *format,
494 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000495{
Mark Hammondef8b6542001-05-13 08:04:26 +0000496 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000497 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000498 if (!PyArg_ParseTuple(args, format,
499 Py_FileSystemDefaultEncoding, &path1,
500 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000502 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000503 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000504 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000505 PyMem_Free(path1);
506 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000507 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000508 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000510 Py_INCREF(Py_None);
511 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000512}
513
Fred Drake699f3522000-06-29 21:12:41 +0000514/* pack a system stat C structure into the Python stat tuple
515 (used by posix_stat() and posix_fstat()) */
516static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000517_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000518{
519 PyObject *v = PyTuple_New(10);
520 if (v == NULL)
521 return NULL;
522
523 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
524#ifdef HAVE_LARGEFILE_SUPPORT
525 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
526#else
527 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
528#endif
529#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
530 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
531#else
532 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
533#endif
534 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
535 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
536 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
537#ifdef HAVE_LARGEFILE_SUPPORT
538 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
539#else
540 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
541#endif
542#if SIZEOF_TIME_T > SIZEOF_LONG
543 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
544 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
545 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
546#else
547 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
548 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
549 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
550#endif
551
552 if (PyErr_Occurred()) {
553 Py_DECREF(v);
554 return NULL;
555 }
556
557 return v;
558}
559
560
Barry Warsaw53699e91996-12-10 23:23:01 +0000561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000562posix_do_stat(PyObject *self, PyObject *args, char *format,
563 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000564{
Fred Drake699f3522000-06-29 21:12:41 +0000565 STRUCT_STAT st;
Mark Hammondef8b6542001-05-13 08:04:26 +0000566 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000567 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000568
569#ifdef MS_WIN32
570 int pathlen;
571 char pathcopy[MAX_PATH];
572#endif /* MS_WIN32 */
573
Mark Hammondef8b6542001-05-13 08:04:26 +0000574 if (!PyArg_ParseTuple(args, format,
575 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000576 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000577
578#ifdef MS_WIN32
579 pathlen = strlen(path);
580 /* the library call can blow up if the file name is too long! */
581 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000582 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000583 errno = ENAMETOOLONG;
584 return posix_error();
585 }
586
587 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000588 /* exception for specific or current drive root */
589 if (!((pathlen == 1) ||
590 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000591 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000592 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000593 {
594 strncpy(pathcopy, path, pathlen);
595 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
596 path = pathcopy;
597 }
598 }
599#endif /* MS_WIN32 */
600
Barry Warsaw53699e91996-12-10 23:23:01 +0000601 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000602 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000603 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000604 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000605 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000606
Mark Hammondef8b6542001-05-13 08:04:26 +0000607 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000608 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000609}
610
611
612/* POSIX methods */
613
Guido van Rossum94f6f721999-01-06 18:42:14 +0000614static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000615"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000616Test for access to a file.";
617
618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000619posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000620{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000621 char *path;
622 int mode;
623 int res;
624
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000625 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000626 return NULL;
627 Py_BEGIN_ALLOW_THREADS
628 res = access(path, mode);
629 Py_END_ALLOW_THREADS
630 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000631}
632
Guido van Rossumd371ff11999-01-25 16:12:23 +0000633#ifndef F_OK
634#define F_OK 0
635#endif
636#ifndef R_OK
637#define R_OK 4
638#endif
639#ifndef W_OK
640#define W_OK 2
641#endif
642#ifndef X_OK
643#define X_OK 1
644#endif
645
646#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000647static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000648"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000649Return the name of the terminal device connected to 'fd'.";
650
651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000652posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000653{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000654 int id;
655 char *ret;
656
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000657 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000658 return NULL;
659
Guido van Rossum94f6f721999-01-06 18:42:14 +0000660 ret = ttyname(id);
661 if (ret == NULL)
662 return(posix_error());
663 return(PyString_FromString(ret));
664}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000665#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000666
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000667#ifdef HAVE_CTERMID
668static char posix_ctermid__doc__[] =
669"ctermid() -> String\n\
670Return the name of the controlling terminal for this process.";
671
672static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000673posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000674{
675 char *ret;
676 char buffer[L_ctermid];
677
678 if (!PyArg_ParseTuple(args, ":ctermid"))
679 return NULL;
680
Greg Wardb48bc172000-03-01 21:51:56 +0000681#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000682 ret = ctermid_r(buffer);
683#else
684 ret = ctermid(buffer);
685#endif
686 if (ret == NULL)
687 return(posix_error());
688 return(PyString_FromString(buffer));
689}
690#endif
691
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000692static char posix_chdir__doc__[] =
693"chdir(path) -> None\n\
694Change the current working directory to the specified path.";
695
Barry Warsaw53699e91996-12-10 23:23:01 +0000696static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000697posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000698{
Mark Hammondef8b6542001-05-13 08:04:26 +0000699 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000700}
701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000702
703static char posix_chmod__doc__[] =
704"chmod(path, mode) -> None\n\
705Change the access permissions of a file.";
706
Barry Warsaw53699e91996-12-10 23:23:01 +0000707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000708posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000709{
Mark Hammondef8b6542001-05-13 08:04:26 +0000710 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000711 int i;
712 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000713 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
714 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000715 return NULL;
716 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000717 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000718 Py_END_ALLOW_THREADS
719 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000720 return posix_error_with_allocated_filename(path);
721 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000722 Py_INCREF(Py_None);
723 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724}
725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000726
Guido van Rossum21142a01999-01-08 21:05:37 +0000727#ifdef HAVE_FSYNC
728static char posix_fsync__doc__[] =
729"fsync(fildes) -> None\n\
730force write of file with filedescriptor to disk.";
731
732static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000733posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000734{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000735 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000736}
737#endif /* HAVE_FSYNC */
738
739#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000740
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000741#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000742extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
743#endif
744
Guido van Rossum21142a01999-01-08 21:05:37 +0000745static char posix_fdatasync__doc__[] =
746"fdatasync(fildes) -> None\n\
747force write of file with filedescriptor to disk.\n\
748 does not force update of metadata.";
749
750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000751posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000752{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000753 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000754}
755#endif /* HAVE_FDATASYNC */
756
757
Fredrik Lundh10723342000-07-10 16:38:09 +0000758#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000759static char posix_chown__doc__[] =
760"chown(path, uid, gid) -> None\n\
761Change the owner and group id of path to the numeric uid and gid.";
762
Barry Warsaw53699e91996-12-10 23:23:01 +0000763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000764posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000765{
Mark Hammondef8b6542001-05-13 08:04:26 +0000766 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000767 int uid, gid;
768 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000769 if (!PyArg_ParseTuple(args, "etii:chown",
770 Py_FileSystemDefaultEncoding, &path,
771 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000772 return NULL;
773 Py_BEGIN_ALLOW_THREADS
774 res = chown(path, (uid_t) uid, (gid_t) gid);
775 Py_END_ALLOW_THREADS
776 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000777 return posix_error_with_allocated_filename(path);
778 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000779 Py_INCREF(Py_None);
780 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000781}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000782#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000784
Guido van Rossum36bc6801995-06-14 22:54:23 +0000785#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000786static char posix_getcwd__doc__[] =
787"getcwd() -> path\n\
788Return a string representing the current working directory.";
789
Barry Warsaw53699e91996-12-10 23:23:01 +0000790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000791posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000792{
793 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000794 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000795 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000796 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000797 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000798 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000799 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000800 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000801 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000802 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000803}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000804#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000806
Guido van Rossumb6775db1994-08-01 11:34:53 +0000807#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000808static char posix_link__doc__[] =
809"link(src, dst) -> None\n\
810Create a hard link to a file.";
811
Barry Warsaw53699e91996-12-10 23:23:01 +0000812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000813posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000814{
Mark Hammondef8b6542001-05-13 08:04:26 +0000815 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000816}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000817#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000819
820static char posix_listdir__doc__[] =
821"listdir(path) -> list_of_strings\n\
822Return a list containing the names of the entries in the directory.\n\
823\n\
824 path: path of directory to list\n\
825\n\
826The list is in arbitrary order. It does not include the special\n\
827entries '.' and '..' even if they are present in the directory.";
828
Barry Warsaw53699e91996-12-10 23:23:01 +0000829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000830posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000831{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000832 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000833 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000834#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000835
Barry Warsaw53699e91996-12-10 23:23:01 +0000836 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000837 HANDLE hFindFile;
838 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000839 /* MAX_PATH characters could mean a bigger encoded string */
840 char namebuf[MAX_PATH*2+5];
841 char *bufptr = namebuf;
842 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000843 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000844
Mark Hammondef8b6542001-05-13 08:04:26 +0000845 if (!PyArg_ParseTuple(args, "et#:listdir",
846 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000847 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000848 ch = namebuf[len-1];
849 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000850 namebuf[len++] = '/';
851 strcpy(namebuf + len, "*.*");
852
Barry Warsaw53699e91996-12-10 23:23:01 +0000853 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000854 return NULL;
855
856 hFindFile = FindFirstFile(namebuf, &FileData);
857 if (hFindFile == INVALID_HANDLE_VALUE) {
858 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000859 if (errno == ERROR_FILE_NOT_FOUND)
860 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000861 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000862 }
863 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000864 if (FileData.cFileName[0] == '.' &&
865 (FileData.cFileName[1] == '\0' ||
866 FileData.cFileName[1] == '.' &&
867 FileData.cFileName[2] == '\0'))
868 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000869 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000870 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000871 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000872 d = NULL;
873 break;
874 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000875 if (PyList_Append(d, v) != 0) {
876 Py_DECREF(v);
877 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000878 d = NULL;
879 break;
880 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000881 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000882 } while (FindNextFile(hFindFile, &FileData) == TRUE);
883
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000884 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +0000885 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886
887 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000888
Tim Peters0bb44a42000-09-15 07:44:49 +0000889#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000890
891#ifndef MAX_PATH
892#define MAX_PATH 250
893#endif
894 char *name, *pt;
895 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000896 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000897 char namebuf[MAX_PATH+5];
898 struct _find_t ep;
899
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000900 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000901 return NULL;
902 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000903 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000904 return NULL;
905 }
906 strcpy(namebuf, name);
907 for (pt = namebuf; *pt; pt++)
908 if (*pt == '/')
909 *pt = '\\';
910 if (namebuf[len-1] != '\\')
911 namebuf[len++] = '\\';
912 strcpy(namebuf + len, "*.*");
913
Barry Warsaw53699e91996-12-10 23:23:01 +0000914 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000915 return NULL;
916
917 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000918 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
919 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000920 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000921 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000922 }
923 do {
924 if (ep.name[0] == '.' &&
925 (ep.name[1] == '\0' ||
926 ep.name[1] == '.' &&
927 ep.name[2] == '\0'))
928 continue;
929 strcpy(namebuf, ep.name);
930 for (pt = namebuf; *pt; pt++)
931 if (isupper(*pt))
932 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000933 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000934 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000935 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000936 d = NULL;
937 break;
938 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000939 if (PyList_Append(d, v) != 0) {
940 Py_DECREF(v);
941 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000942 d = NULL;
943 break;
944 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000945 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000946 } while (_dos_findnext(&ep) == 0);
947
948 return d;
949
Tim Peters0bb44a42000-09-15 07:44:49 +0000950#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000951
952#ifndef MAX_PATH
953#define MAX_PATH CCHMAXPATH
954#endif
955 char *name, *pt;
956 int len;
957 PyObject *d, *v;
958 char namebuf[MAX_PATH+5];
959 HDIR hdir = 1;
960 ULONG srchcnt = 1;
961 FILEFINDBUF3 ep;
962 APIRET rc;
963
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000964 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000965 return NULL;
966 if (len >= MAX_PATH) {
967 PyErr_SetString(PyExc_ValueError, "path too long");
968 return NULL;
969 }
970 strcpy(namebuf, name);
971 for (pt = namebuf; *pt; pt++)
972 if (*pt == '/')
973 *pt = '\\';
974 if (namebuf[len-1] != '\\')
975 namebuf[len++] = '\\';
976 strcpy(namebuf + len, "*.*");
977
978 if ((d = PyList_New(0)) == NULL)
979 return NULL;
980
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000981 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
982 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000983 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000984 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
985 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
986 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000987
988 if (rc != NO_ERROR) {
989 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000990 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000991 }
992
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000993 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000994 do {
995 if (ep.achName[0] == '.'
996 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000997 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000998
999 strcpy(namebuf, ep.achName);
1000
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001001 /* Leave Case of Name Alone -- In Native Form */
1002 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001003
1004 v = PyString_FromString(namebuf);
1005 if (v == NULL) {
1006 Py_DECREF(d);
1007 d = NULL;
1008 break;
1009 }
1010 if (PyList_Append(d, v) != 0) {
1011 Py_DECREF(v);
1012 Py_DECREF(d);
1013 d = NULL;
1014 break;
1015 }
1016 Py_DECREF(v);
1017 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1018 }
1019
1020 return d;
1021#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001022
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001023 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001024 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001025 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001026 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001027 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001028 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001029 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001030 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001031 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001032 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001033 closedir(dirp);
1034 return NULL;
1035 }
1036 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001037 if (ep->d_name[0] == '.' &&
1038 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001039 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001040 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001041 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001042 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001043 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001044 d = NULL;
1045 break;
1046 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001047 if (PyList_Append(d, v) != 0) {
1048 Py_DECREF(v);
1049 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001050 d = NULL;
1051 break;
1052 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001053 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001054 }
1055 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001056
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001057 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001058
Tim Peters0bb44a42000-09-15 07:44:49 +00001059#endif /* which OS */
1060} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061
Mark Hammondef8b6542001-05-13 08:04:26 +00001062#ifdef MS_WIN32
1063/* A helper function for abspath on win32 */
1064static PyObject *
1065posix__getfullpathname(PyObject *self, PyObject *args)
1066{
1067 /* assume encoded strings wont more than double no of chars */
1068 char inbuf[MAX_PATH*2];
1069 char *inbufp = inbuf;
1070 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1071 char outbuf[MAX_PATH*2];
1072 char *temp;
1073 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1074 Py_FileSystemDefaultEncoding, &inbufp,
1075 &insize))
1076 return NULL;
1077 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1078 outbuf, &temp))
1079 return win32_error("GetFullPathName", inbuf);
1080 return PyString_FromString(outbuf);
1081} /* end of posix__getfullpathname */
1082#endif /* MS_WIN32 */
1083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001084static char posix_mkdir__doc__[] =
1085"mkdir(path [, mode=0777]) -> None\n\
1086Create a directory.";
1087
Barry Warsaw53699e91996-12-10 23:23:01 +00001088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001089posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001090{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001091 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001092 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001093 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001094 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1095 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001096 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001097 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001098#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001099 res = mkdir(path);
1100#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001101 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001102#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001103 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001104 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001105 return posix_error_with_allocated_filename(path);
1106 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001107 Py_INCREF(Py_None);
1108 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001109}
1110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001111
Guido van Rossumb6775db1994-08-01 11:34:53 +00001112#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001113static char posix_nice__doc__[] =
1114"nice(inc) -> new_priority\n\
1115Decrease the priority of process and return new priority.";
1116
Barry Warsaw53699e91996-12-10 23:23:01 +00001117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001118posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001119{
1120 int increment, value;
1121
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001122 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001123 return NULL;
1124 value = nice(increment);
1125 if (value == -1)
1126 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001127 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001128}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001129#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001131
1132static char posix_rename__doc__[] =
1133"rename(old, new) -> None\n\
1134Rename a file or directory.";
1135
Barry Warsaw53699e91996-12-10 23:23:01 +00001136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001137posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001138{
Mark Hammondef8b6542001-05-13 08:04:26 +00001139 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001140}
1141
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001142
1143static char posix_rmdir__doc__[] =
1144"rmdir(path) -> None\n\
1145Remove a directory.";
1146
Barry Warsaw53699e91996-12-10 23:23:01 +00001147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001148posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001149{
Mark Hammondef8b6542001-05-13 08:04:26 +00001150 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001151}
1152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001153
1154static char posix_stat__doc__[] =
1155"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1156Perform a stat system call on the given path.";
1157
Barry Warsaw53699e91996-12-10 23:23:01 +00001158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001159posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001160{
Mark Hammondef8b6542001-05-13 08:04:26 +00001161 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162}
1163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001164
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001165#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001166static char posix_system__doc__[] =
1167"system(command) -> exit_status\n\
1168Execute the command (a string) in a subshell.";
1169
Barry Warsaw53699e91996-12-10 23:23:01 +00001170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001171posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001172{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001173 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001174 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001175 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001176 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001177 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001178 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001179 Py_END_ALLOW_THREADS
1180 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001181}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001182#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001183
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001184
1185static char posix_umask__doc__[] =
1186"umask(new_mask) -> old_mask\n\
1187Set the current numeric umask and return the previous umask.";
1188
Barry Warsaw53699e91996-12-10 23:23:01 +00001189static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001190posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191{
1192 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001193 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001194 return NULL;
1195 i = umask(i);
1196 if (i < 0)
1197 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001198 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001199}
1200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001201
1202static char posix_unlink__doc__[] =
1203"unlink(path) -> None\n\
1204Remove a file (same as remove(path)).";
1205
1206static char posix_remove__doc__[] =
1207"remove(path) -> None\n\
1208Remove a file (same as unlink(path)).";
1209
Barry Warsaw53699e91996-12-10 23:23:01 +00001210static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001211posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001212{
Mark Hammondef8b6542001-05-13 08:04:26 +00001213 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214}
1215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001216
Guido van Rossumb6775db1994-08-01 11:34:53 +00001217#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001218static char posix_uname__doc__[] =
1219"uname() -> (sysname, nodename, release, version, machine)\n\
1220Return a tuple identifying the current operating system.";
1221
Barry Warsaw53699e91996-12-10 23:23:01 +00001222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001223posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001224{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001225 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001226 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001227 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001228 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001229 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001230 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001231 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001232 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001233 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001234 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001235 u.sysname,
1236 u.nodename,
1237 u.release,
1238 u.version,
1239 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001240}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001241#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001243
1244static char posix_utime__doc__[] =
1245"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001246utime(path, None) -> None\n\
1247Set the access and modified time of the file to the given values. If the\n\
1248second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001249
Barry Warsaw53699e91996-12-10 23:23:01 +00001250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001251posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001253 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001254 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001255 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001256 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001257
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001258/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001259#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001260 struct utimbuf buf;
1261#define ATIME buf.actime
1262#define MTIME buf.modtime
1263#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001264#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001265 time_t buf[2];
1266#define ATIME buf[0]
1267#define MTIME buf[1]
1268#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001269#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001270
Barry Warsaw3cef8562000-05-01 16:17:24 +00001271 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001272 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001273 if (arg == Py_None) {
1274 /* optional time values not given */
1275 Py_BEGIN_ALLOW_THREADS
1276 res = utime(path, NULL);
1277 Py_END_ALLOW_THREADS
1278 }
1279 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1280 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001281 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001282 return NULL;
1283 }
1284 else {
1285 ATIME = atime;
1286 MTIME = mtime;
1287 Py_BEGIN_ALLOW_THREADS
1288 res = utime(path, UTIME_ARG);
1289 Py_END_ALLOW_THREADS
1290 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001291 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001292 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001293 Py_INCREF(Py_None);
1294 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001295#undef UTIME_ARG
1296#undef ATIME
1297#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001298}
1299
Guido van Rossum85e3b011991-06-03 12:42:10 +00001300
Guido van Rossum3b066191991-06-04 19:40:25 +00001301/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001302
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001303static char posix__exit__doc__[] =
1304"_exit(status)\n\
1305Exit to the system with specified status, without normal exit processing.";
1306
Barry Warsaw53699e91996-12-10 23:23:01 +00001307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001308posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001309{
1310 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001311 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001312 return NULL;
1313 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001314 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001315}
1316
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001317
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001318#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001319static char posix_execv__doc__[] =
1320"execv(path, args)\n\
1321Execute an executable path with arguments, replacing current process.\n\
1322\n\
1323 path: path of executable file\n\
1324 args: tuple or list of strings";
1325
Barry Warsaw53699e91996-12-10 23:23:01 +00001326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001327posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001328{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001329 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001330 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001331 char **argvlist;
1332 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001333 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001334
Guido van Rossum89b33251993-10-22 14:26:06 +00001335 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001336 argv is a list or tuple of strings. */
1337
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001338 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001339 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001340 if (PyList_Check(argv)) {
1341 argc = PyList_Size(argv);
1342 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001343 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001344 else if (PyTuple_Check(argv)) {
1345 argc = PyTuple_Size(argv);
1346 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001347 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001348 else {
Fred Drake661ea262000-10-24 19:57:45 +00001349 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001350 return NULL;
1351 }
1352
1353 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001354 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001355 return NULL;
1356 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001357
Barry Warsaw53699e91996-12-10 23:23:01 +00001358 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001359 if (argvlist == NULL)
1360 return NULL;
1361 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001362 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1363 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001364 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001365 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001366 return NULL;
1367
Guido van Rossum85e3b011991-06-03 12:42:10 +00001368 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001369 }
1370 argvlist[argc] = NULL;
1371
Guido van Rossumb6775db1994-08-01 11:34:53 +00001372#ifdef BAD_EXEC_PROTOTYPES
1373 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001374#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001375 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001376#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001377
Guido van Rossum85e3b011991-06-03 12:42:10 +00001378 /* If we get here it's definitely an error */
1379
Barry Warsaw53699e91996-12-10 23:23:01 +00001380 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001381 return posix_error();
1382}
1383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001384
1385static char posix_execve__doc__[] =
1386"execve(path, args, env)\n\
1387Execute a path with arguments and environment, replacing current process.\n\
1388\n\
1389 path: path of executable file\n\
1390 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001391 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001392
Barry Warsaw53699e91996-12-10 23:23:01 +00001393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001394posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001395{
1396 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001397 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001398 char **argvlist;
1399 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001400 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001401 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001402 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001403
1404 /* execve has three arguments: (path, argv, env), where
1405 argv is a list or tuple of strings and env is a dictionary
1406 like posix.environ. */
1407
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001408 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001409 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001410 if (PyList_Check(argv)) {
1411 argc = PyList_Size(argv);
1412 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001413 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001414 else if (PyTuple_Check(argv)) {
1415 argc = PyTuple_Size(argv);
1416 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001417 }
1418 else {
Fred Drake661ea262000-10-24 19:57:45 +00001419 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001420 return NULL;
1421 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001422 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001423 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001424 return NULL;
1425 }
1426
Guido van Rossum50422b42000-04-26 20:34:28 +00001427 if (argc == 0) {
1428 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001429 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001430 return NULL;
1431 }
1432
Barry Warsaw53699e91996-12-10 23:23:01 +00001433 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001434 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001435 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001436 return NULL;
1437 }
1438 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001439 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001440 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001441 &argvlist[i]))
1442 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001443 goto fail_1;
1444 }
1445 }
1446 argvlist[argc] = NULL;
1447
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001448 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001449 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001450 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001451 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001452 goto fail_1;
1453 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001454 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001455 keys = PyMapping_Keys(env);
1456 vals = PyMapping_Values(env);
1457 if (!keys || !vals)
1458 goto fail_2;
1459
1460 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001461 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001462
1463 key = PyList_GetItem(keys, pos);
1464 val = PyList_GetItem(vals, pos);
1465 if (!key || !val)
1466 goto fail_2;
1467
Fred Drake661ea262000-10-24 19:57:45 +00001468 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1469 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001470 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001471 goto fail_2;
1472 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001473
1474#if defined(PYOS_OS2)
1475 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1476 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1477#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001478 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001479 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001480 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001481 goto fail_2;
1482 }
1483 sprintf(p, "%s=%s", k, v);
1484 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001485#if defined(PYOS_OS2)
1486 }
1487#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001488 }
1489 envlist[envc] = 0;
1490
Guido van Rossumb6775db1994-08-01 11:34:53 +00001491
1492#ifdef BAD_EXEC_PROTOTYPES
1493 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001494#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001495 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001496#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001497
1498 /* If we get here it's definitely an error */
1499
1500 (void) posix_error();
1501
1502 fail_2:
1503 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001504 PyMem_DEL(envlist[envc]);
1505 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001506 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001507 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001508 Py_XDECREF(vals);
1509 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001510 return NULL;
1511}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001512#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001513
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001514
Guido van Rossuma1065681999-01-25 23:20:23 +00001515#ifdef HAVE_SPAWNV
1516static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001517"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001518Execute an executable path with arguments, replacing current process.\n\
1519\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001520 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001521 path: path of executable file\n\
1522 args: tuple or list of strings";
1523
1524static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001525posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001526{
1527 char *path;
1528 PyObject *argv;
1529 char **argvlist;
1530 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001531 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001532 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001533
1534 /* spawnv has three arguments: (mode, path, argv), where
1535 argv is a list or tuple of strings. */
1536
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001537 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001538 return NULL;
1539 if (PyList_Check(argv)) {
1540 argc = PyList_Size(argv);
1541 getitem = PyList_GetItem;
1542 }
1543 else if (PyTuple_Check(argv)) {
1544 argc = PyTuple_Size(argv);
1545 getitem = PyTuple_GetItem;
1546 }
1547 else {
Fred Drake661ea262000-10-24 19:57:45 +00001548 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001549 return NULL;
1550 }
1551
1552 argvlist = PyMem_NEW(char *, argc+1);
1553 if (argvlist == NULL)
1554 return NULL;
1555 for (i = 0; i < argc; i++) {
1556 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1557 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001558 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001559 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001560 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001561 }
1562 }
1563 argvlist[argc] = NULL;
1564
Guido van Rossum246bc171999-02-01 23:54:31 +00001565 if (mode == _OLD_P_OVERLAY)
1566 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001567 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001568
1569 PyMem_DEL(argvlist);
1570
Fred Drake699f3522000-06-29 21:12:41 +00001571 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001572 return posix_error();
1573 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001574#if SIZEOF_LONG == SIZEOF_VOID_P
1575 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001576#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001577 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001578#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001579}
1580
1581
1582static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001583"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001584Execute a path with arguments and environment, replacing current process.\n\
1585\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001586 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001587 path: path of executable file\n\
1588 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001589 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001590
1591static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001592posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001593{
1594 char *path;
1595 PyObject *argv, *env;
1596 char **argvlist;
1597 char **envlist;
1598 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1599 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001600 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001601 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001602
1603 /* spawnve has four arguments: (mode, path, argv, env), where
1604 argv is a list or tuple of strings and env is a dictionary
1605 like posix.environ. */
1606
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001607 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001608 return NULL;
1609 if (PyList_Check(argv)) {
1610 argc = PyList_Size(argv);
1611 getitem = PyList_GetItem;
1612 }
1613 else if (PyTuple_Check(argv)) {
1614 argc = PyTuple_Size(argv);
1615 getitem = PyTuple_GetItem;
1616 }
1617 else {
Fred Drake661ea262000-10-24 19:57:45 +00001618 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001619 return NULL;
1620 }
1621 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001622 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001623 return NULL;
1624 }
1625
1626 argvlist = PyMem_NEW(char *, argc+1);
1627 if (argvlist == NULL) {
1628 PyErr_NoMemory();
1629 return NULL;
1630 }
1631 for (i = 0; i < argc; i++) {
1632 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001633 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001634 &argvlist[i]))
1635 {
1636 goto fail_1;
1637 }
1638 }
1639 argvlist[argc] = NULL;
1640
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001641 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001642 envlist = PyMem_NEW(char *, i + 1);
1643 if (envlist == NULL) {
1644 PyErr_NoMemory();
1645 goto fail_1;
1646 }
1647 envc = 0;
1648 keys = PyMapping_Keys(env);
1649 vals = PyMapping_Values(env);
1650 if (!keys || !vals)
1651 goto fail_2;
1652
1653 for (pos = 0; pos < i; pos++) {
1654 char *p, *k, *v;
1655
1656 key = PyList_GetItem(keys, pos);
1657 val = PyList_GetItem(vals, pos);
1658 if (!key || !val)
1659 goto fail_2;
1660
Fred Drake661ea262000-10-24 19:57:45 +00001661 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1662 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001663 {
1664 goto fail_2;
1665 }
1666 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1667 if (p == NULL) {
1668 PyErr_NoMemory();
1669 goto fail_2;
1670 }
1671 sprintf(p, "%s=%s", k, v);
1672 envlist[envc++] = p;
1673 }
1674 envlist[envc] = 0;
1675
Guido van Rossum246bc171999-02-01 23:54:31 +00001676 if (mode == _OLD_P_OVERLAY)
1677 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001678 spawnval = _spawnve(mode, path, argvlist, envlist);
1679 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001680 (void) posix_error();
1681 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001682#if SIZEOF_LONG == SIZEOF_VOID_P
1683 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001684#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001685 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001686#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001687
1688 fail_2:
1689 while (--envc >= 0)
1690 PyMem_DEL(envlist[envc]);
1691 PyMem_DEL(envlist);
1692 fail_1:
1693 PyMem_DEL(argvlist);
1694 Py_XDECREF(vals);
1695 Py_XDECREF(keys);
1696 return res;
1697}
1698#endif /* HAVE_SPAWNV */
1699
1700
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001701#ifdef HAVE_FORK1
1702static char posix_fork1__doc__[] =
1703"fork1() -> pid\n\
1704Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1705\n\
1706Return 0 to child process and PID of child to parent process.";
1707
1708static PyObject *
1709posix_fork1(self, args)
1710 PyObject *self;
1711 PyObject *args;
1712{
1713 int pid;
1714 if (!PyArg_ParseTuple(args, ":fork1"))
1715 return NULL;
1716 pid = fork1();
1717 if (pid == -1)
1718 return posix_error();
1719 PyOS_AfterFork();
1720 return PyInt_FromLong((long)pid);
1721}
1722#endif
1723
1724
Guido van Rossumad0ee831995-03-01 10:34:45 +00001725#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001726static char posix_fork__doc__[] =
1727"fork() -> pid\n\
1728Fork a child process.\n\
1729\n\
1730Return 0 to child process and PID of child to parent process.";
1731
Barry Warsaw53699e91996-12-10 23:23:01 +00001732static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001733posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001734{
1735 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001736 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001737 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001738 pid = fork();
1739 if (pid == -1)
1740 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001741 if (pid == 0)
1742 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001743 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001744}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001745#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001746
Fred Drake8cef4cf2000-06-28 16:40:38 +00001747#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1748#ifdef HAVE_PTY_H
1749#include <pty.h>
1750#else
1751#ifdef HAVE_LIBUTIL_H
1752#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001753#endif /* HAVE_LIBUTIL_H */
1754#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001755#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001756
Thomas Wouters70c21a12000-07-14 14:28:33 +00001757#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001758static char posix_openpty__doc__[] =
1759"openpty() -> (master_fd, slave_fd)\n\
1760Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1761
1762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001763posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001764{
1765 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001766#ifndef HAVE_OPENPTY
1767 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001768#endif
1769
Fred Drake8cef4cf2000-06-28 16:40:38 +00001770 if (!PyArg_ParseTuple(args, ":openpty"))
1771 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001772
1773#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001774 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1775 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001776#else
1777 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1778 if (slave_name == NULL)
1779 return posix_error();
1780
1781 slave_fd = open(slave_name, O_RDWR);
1782 if (slave_fd < 0)
1783 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001784#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001785
Fred Drake8cef4cf2000-06-28 16:40:38 +00001786 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001787
Fred Drake8cef4cf2000-06-28 16:40:38 +00001788}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001789#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001790
1791#ifdef HAVE_FORKPTY
1792static char posix_forkpty__doc__[] =
1793"forkpty() -> (pid, master_fd)\n\
1794Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1795Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1796To both, return fd of newly opened pseudo-terminal.\n";
1797
1798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001799posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001800{
1801 int master_fd, pid;
1802
1803 if (!PyArg_ParseTuple(args, ":forkpty"))
1804 return NULL;
1805 pid = forkpty(&master_fd, NULL, NULL, NULL);
1806 if (pid == -1)
1807 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001808 if (pid == 0)
1809 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001810 return Py_BuildValue("(ii)", pid, master_fd);
1811}
1812#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001813
Guido van Rossumad0ee831995-03-01 10:34:45 +00001814#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001815static char posix_getegid__doc__[] =
1816"getegid() -> egid\n\
1817Return the current process's effective group id.";
1818
Barry Warsaw53699e91996-12-10 23:23:01 +00001819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001820posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001821{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001822 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001823 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001824 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001825}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001826#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001828
Guido van Rossumad0ee831995-03-01 10:34:45 +00001829#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001830static char posix_geteuid__doc__[] =
1831"geteuid() -> euid\n\
1832Return the current process's effective user id.";
1833
Barry Warsaw53699e91996-12-10 23:23:01 +00001834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001835posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001836{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001837 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001838 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001839 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001840}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001841#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001842
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001843
Guido van Rossumad0ee831995-03-01 10:34:45 +00001844#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001845static char posix_getgid__doc__[] =
1846"getgid() -> gid\n\
1847Return the current process's group id.";
1848
Barry Warsaw53699e91996-12-10 23:23:01 +00001849static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001850posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001851{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001852 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001853 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001854 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001855}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001856#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001857
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001858
1859static char posix_getpid__doc__[] =
1860"getpid() -> pid\n\
1861Return the current process id";
1862
Barry Warsaw53699e91996-12-10 23:23:01 +00001863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001864posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001865{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001866 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001867 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001868 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001869}
1870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001871
Fred Drakec9680921999-12-13 16:37:25 +00001872#ifdef HAVE_GETGROUPS
1873static char posix_getgroups__doc__[] = "\
1874getgroups() -> list of group IDs\n\
1875Return list of supplemental group IDs for the process.";
1876
1877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001878posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001879{
1880 PyObject *result = NULL;
1881
1882 if (PyArg_ParseTuple(args, ":getgroups")) {
1883#ifdef NGROUPS_MAX
1884#define MAX_GROUPS NGROUPS_MAX
1885#else
1886 /* defined to be 16 on Solaris7, so this should be a small number */
1887#define MAX_GROUPS 64
1888#endif
1889 gid_t grouplist[MAX_GROUPS];
1890 int n;
1891
1892 n = getgroups(MAX_GROUPS, grouplist);
1893 if (n < 0)
1894 posix_error();
1895 else {
1896 result = PyList_New(n);
1897 if (result != NULL) {
1898 PyObject *o;
1899 int i;
1900 for (i = 0; i < n; ++i) {
1901 o = PyInt_FromLong((long)grouplist[i]);
1902 if (o == NULL) {
1903 Py_DECREF(result);
1904 result = NULL;
1905 break;
1906 }
1907 PyList_SET_ITEM(result, i, o);
1908 }
1909 }
1910 }
1911 }
1912 return result;
1913}
1914#endif
1915
Guido van Rossumb6775db1994-08-01 11:34:53 +00001916#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001917static char posix_getpgrp__doc__[] =
1918"getpgrp() -> pgrp\n\
1919Return the current process group id.";
1920
Barry Warsaw53699e91996-12-10 23:23:01 +00001921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001922posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001923{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001924 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001925 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001926#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001927 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001928#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001929 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001930#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001931}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001932#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001934
Guido van Rossumb6775db1994-08-01 11:34:53 +00001935#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001936static char posix_setpgrp__doc__[] =
1937"setpgrp() -> None\n\
1938Make this process a session leader.";
1939
Barry Warsaw53699e91996-12-10 23:23:01 +00001940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001941posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001942{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001943 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001944 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001945#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001946 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001947#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001948 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001949#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001950 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001951 Py_INCREF(Py_None);
1952 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001953}
1954
Guido van Rossumb6775db1994-08-01 11:34:53 +00001955#endif /* HAVE_SETPGRP */
1956
Guido van Rossumad0ee831995-03-01 10:34:45 +00001957#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001958static char posix_getppid__doc__[] =
1959"getppid() -> ppid\n\
1960Return the parent's process id.";
1961
Barry Warsaw53699e91996-12-10 23:23:01 +00001962static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001963posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001964{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001965 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001966 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001967 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001968}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001969#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001970
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001971
Fred Drake12c6e2d1999-12-14 21:25:03 +00001972#ifdef HAVE_GETLOGIN
1973static char posix_getlogin__doc__[] = "\
1974getlogin() -> string\n\
1975Return the actual login name.";
1976
1977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001978posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001979{
1980 PyObject *result = NULL;
1981
1982 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00001983 char *name;
1984 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001985
Fred Drakea30680b2000-12-06 21:24:28 +00001986 errno = 0;
1987 name = getlogin();
1988 if (name == NULL) {
1989 if (errno)
1990 posix_error();
1991 else
1992 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00001993 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00001994 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00001995 else
1996 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00001997 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001998 }
1999 return result;
2000}
2001#endif
2002
Guido van Rossumad0ee831995-03-01 10:34:45 +00002003#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002004static char posix_getuid__doc__[] =
2005"getuid() -> uid\n\
2006Return the current process's user id.";
2007
Barry Warsaw53699e91996-12-10 23:23:01 +00002008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002009posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002010{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002011 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002012 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002013 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002014}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002015#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002017
Guido van Rossumad0ee831995-03-01 10:34:45 +00002018#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002019static char posix_kill__doc__[] =
2020"kill(pid, sig) -> None\n\
2021Kill a process with a signal.";
2022
Barry Warsaw53699e91996-12-10 23:23:01 +00002023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002024posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002025{
2026 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002027 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002028 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002029#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002030 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2031 APIRET rc;
2032 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002033 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002034
2035 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2036 APIRET rc;
2037 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002038 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002039
2040 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002041 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002042#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002043 if (kill(pid, sig) == -1)
2044 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002045#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002046 Py_INCREF(Py_None);
2047 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002048}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002049#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002050
Guido van Rossumc0125471996-06-28 18:55:32 +00002051#ifdef HAVE_PLOCK
2052
2053#ifdef HAVE_SYS_LOCK_H
2054#include <sys/lock.h>
2055#endif
2056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002057static char posix_plock__doc__[] =
2058"plock(op) -> None\n\
2059Lock program segments into memory.";
2060
Barry Warsaw53699e91996-12-10 23:23:01 +00002061static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002062posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002063{
2064 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002065 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002066 return NULL;
2067 if (plock(op) == -1)
2068 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002069 Py_INCREF(Py_None);
2070 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002071}
2072#endif
2073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002074
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002075#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002076static char posix_popen__doc__[] =
2077"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2078Open a pipe to/from a command returning a file object.";
2079
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002080#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002081static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002082async_system(const char *command)
2083{
2084 char *p, errormsg[256], args[1024];
2085 RESULTCODES rcodes;
2086 APIRET rc;
2087 char *shell = getenv("COMSPEC");
2088 if (!shell)
2089 shell = "cmd";
2090
2091 strcpy(args, shell);
2092 p = &args[ strlen(args)+1 ];
2093 strcpy(p, "/c ");
2094 strcat(p, command);
2095 p += strlen(p) + 1;
2096 *p = '\0';
2097
2098 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002099 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002100 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002101 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002102 &rcodes, shell);
2103 return rc;
2104}
2105
Guido van Rossumd48f2521997-12-05 22:19:34 +00002106static FILE *
2107popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002108{
2109 HFILE rhan, whan;
2110 FILE *retfd = NULL;
2111 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2112
Guido van Rossumd48f2521997-12-05 22:19:34 +00002113 if (rc != NO_ERROR) {
2114 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002115 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002116 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002117
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002118 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2119 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002120
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002121 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2122 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002123
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002124 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2125 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002126
2127 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002128 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002129 }
2130
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002131 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2132 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002133
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002134 close(oldfd); /* And Close Saved STDOUT Handle */
2135 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002136
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002137 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2138 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002139
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002140 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2141 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002142
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002143 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2144 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002145
2146 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002147 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002148 }
2149
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002150 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2151 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002152
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002153 close(oldfd); /* And Close Saved STDIN Handle */
2154 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002155
Guido van Rossumd48f2521997-12-05 22:19:34 +00002156 } else {
2157 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002158 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002159 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002160}
2161
2162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002163posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002164{
2165 char *name;
2166 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002167 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002168 FILE *fp;
2169 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002170 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002171 return NULL;
2172 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002173 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002174 Py_END_ALLOW_THREADS
2175 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002176 return os2_error(err);
2177
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002178 f = PyFile_FromFile(fp, name, mode, fclose);
2179 if (f != NULL)
2180 PyFile_SetBufSize(f, bufsize);
2181 return f;
2182}
2183
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002184#elif defined(MS_WIN32)
2185
2186/*
2187 * Portable 'popen' replacement for Win32.
2188 *
2189 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2190 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002191 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002192 */
2193
2194#include <malloc.h>
2195#include <io.h>
2196#include <fcntl.h>
2197
2198/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2199#define POPEN_1 1
2200#define POPEN_2 2
2201#define POPEN_3 3
2202#define POPEN_4 4
2203
2204static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002205static int _PyPclose(FILE *file);
2206
2207/*
2208 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002209 * for use when retrieving the process exit code. See _PyPclose() below
2210 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002211 */
2212static PyObject *_PyPopenProcs = NULL;
2213
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002214
2215/* popen that works from a GUI.
2216 *
2217 * The result of this function is a pipe (file) connected to the
2218 * processes stdin or stdout, depending on the requested mode.
2219 */
2220
2221static PyObject *
2222posix_popen(PyObject *self, PyObject *args)
2223{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002224 PyObject *f, *s;
2225 int tm = 0;
2226
2227 char *cmdstring;
2228 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002229 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002230 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002231 return NULL;
2232
2233 s = PyTuple_New(0);
2234
2235 if (*mode == 'r')
2236 tm = _O_RDONLY;
2237 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002238 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002239 return NULL;
2240 } else
2241 tm = _O_WRONLY;
2242
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002243 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002244 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002245 return NULL;
2246 }
2247
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002248 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002249 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002250 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002251 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002252 else
2253 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2254
2255 return f;
2256}
2257
2258/* Variation on win32pipe.popen
2259 *
2260 * The result of this function is a pipe (file) connected to the
2261 * process's stdin, and a pipe connected to the process's stdout.
2262 */
2263
2264static PyObject *
2265win32_popen2(PyObject *self, PyObject *args)
2266{
2267 PyObject *f;
2268 int tm=0;
2269
2270 char *cmdstring;
2271 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002272 int bufsize = -1;
2273 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002274 return NULL;
2275
2276 if (*mode == 't')
2277 tm = _O_TEXT;
2278 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002279 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002280 return NULL;
2281 } else
2282 tm = _O_BINARY;
2283
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002284 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002285 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002286 return NULL;
2287 }
2288
2289 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002290
2291 return f;
2292}
2293
2294/*
2295 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002296 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002297 * The result of this function is 3 pipes - the process's stdin,
2298 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002299 */
2300
2301static PyObject *
2302win32_popen3(PyObject *self, PyObject *args)
2303{
2304 PyObject *f;
2305 int tm = 0;
2306
2307 char *cmdstring;
2308 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002309 int bufsize = -1;
2310 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002311 return NULL;
2312
2313 if (*mode == 't')
2314 tm = _O_TEXT;
2315 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002316 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002317 return NULL;
2318 } else
2319 tm = _O_BINARY;
2320
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002321 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002322 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002323 return NULL;
2324 }
2325
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002326 f = _PyPopen(cmdstring, tm, POPEN_3);
2327
2328 return f;
2329}
2330
2331/*
2332 * Variation on win32pipe.popen
2333 *
2334 * The result of this function is 2 pipes - the processes stdin,
2335 * and stdout+stderr combined as a single pipe.
2336 */
2337
2338static PyObject *
2339win32_popen4(PyObject *self, PyObject *args)
2340{
2341 PyObject *f;
2342 int tm = 0;
2343
2344 char *cmdstring;
2345 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002346 int bufsize = -1;
2347 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002348 return NULL;
2349
2350 if (*mode == 't')
2351 tm = _O_TEXT;
2352 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002353 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002354 return NULL;
2355 } else
2356 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002357
2358 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002359 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002360 return NULL;
2361 }
2362
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002363 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002364
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002365 return f;
2366}
2367
Mark Hammond08501372001-01-31 07:30:29 +00002368static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002369_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002370 HANDLE hStdin,
2371 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002372 HANDLE hStderr,
2373 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002374{
2375 PROCESS_INFORMATION piProcInfo;
2376 STARTUPINFO siStartInfo;
2377 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002378 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002379 int i;
2380 int x;
2381
2382 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2383 s1 = (char *)_alloca(i);
2384 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2385 return x;
2386 if (GetVersion() < 0x80000000) {
2387 /*
2388 * NT/2000
2389 */
2390 x = i + strlen(s3) + strlen(cmdstring) + 1;
2391 s2 = (char *)_alloca(x);
2392 ZeroMemory(s2, x);
2393 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2394 }
2395 else {
2396 /*
2397 * Oh gag, we're on Win9x. Use the workaround listed in
2398 * KB: Q150956
2399 */
Mark Hammond08501372001-01-31 07:30:29 +00002400 char modulepath[_MAX_PATH];
2401 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002402 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2403 for (i = x = 0; modulepath[i]; i++)
2404 if (modulepath[i] == '\\')
2405 x = i+1;
2406 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002407 /* Create the full-name to w9xpopen, so we can test it exists */
2408 strncat(modulepath,
2409 szConsoleSpawn,
2410 (sizeof(modulepath)/sizeof(modulepath[0]))
2411 -strlen(modulepath));
2412 if (stat(modulepath, &statinfo) != 0) {
2413 /* Eeek - file-not-found - possibly an embedding
2414 situation - see if we can locate it in sys.prefix
2415 */
2416 strncpy(modulepath,
2417 Py_GetExecPrefix(),
2418 sizeof(modulepath)/sizeof(modulepath[0]));
2419 if (modulepath[strlen(modulepath)-1] != '\\')
2420 strcat(modulepath, "\\");
2421 strncat(modulepath,
2422 szConsoleSpawn,
2423 (sizeof(modulepath)/sizeof(modulepath[0]))
2424 -strlen(modulepath));
2425 /* No where else to look - raise an easily identifiable
2426 error, rather than leaving Windows to report
2427 "file not found" - as the user is probably blissfully
2428 unaware this shim EXE is used, and it will confuse them.
2429 (well, it confused me for a while ;-)
2430 */
2431 if (stat(modulepath, &statinfo) != 0) {
2432 PyErr_Format(PyExc_RuntimeError,
2433 "Can not locate '%s' which is needed "
2434 "for popen to work on this platform.",
2435 szConsoleSpawn);
2436 return FALSE;
2437 }
2438 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002439 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2440 strlen(modulepath) +
2441 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002442
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002443 s2 = (char *)_alloca(x);
2444 ZeroMemory(s2, x);
2445 sprintf(
2446 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002447 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002448 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002449 s1,
2450 s3,
2451 cmdstring);
2452 }
2453 }
2454
2455 /* Could be an else here to try cmd.exe / command.com in the path
2456 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002457 else {
2458 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2459 return FALSE;
2460 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002461
2462 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2463 siStartInfo.cb = sizeof(STARTUPINFO);
2464 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2465 siStartInfo.hStdInput = hStdin;
2466 siStartInfo.hStdOutput = hStdout;
2467 siStartInfo.hStdError = hStderr;
2468 siStartInfo.wShowWindow = SW_HIDE;
2469
2470 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002471 s2,
2472 NULL,
2473 NULL,
2474 TRUE,
2475 CREATE_NEW_CONSOLE,
2476 NULL,
2477 NULL,
2478 &siStartInfo,
2479 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002480 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002481 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002482
Mark Hammondb37a3732000-08-14 04:47:33 +00002483 /* Return process handle */
2484 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002485 return TRUE;
2486 }
Mark Hammond08501372001-01-31 07:30:29 +00002487 win32_error("CreateProcess", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002488 return FALSE;
2489}
2490
2491/* The following code is based off of KB: Q190351 */
2492
2493static PyObject *
2494_PyPopen(char *cmdstring, int mode, int n)
2495{
2496 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2497 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002498 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002499
2500 SECURITY_ATTRIBUTES saAttr;
2501 BOOL fSuccess;
2502 int fd1, fd2, fd3;
2503 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002504 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002505 PyObject *f;
2506
2507 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2508 saAttr.bInheritHandle = TRUE;
2509 saAttr.lpSecurityDescriptor = NULL;
2510
2511 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2512 return win32_error("CreatePipe", NULL);
2513
2514 /* Create new output read handle and the input write handle. Set
2515 * the inheritance properties to FALSE. Otherwise, the child inherits
2516 * the these handles; resulting in non-closeable handles to the pipes
2517 * being created. */
2518 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002519 GetCurrentProcess(), &hChildStdinWrDup, 0,
2520 FALSE,
2521 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002522 if (!fSuccess)
2523 return win32_error("DuplicateHandle", NULL);
2524
2525 /* Close the inheritable version of ChildStdin
2526 that we're using. */
2527 CloseHandle(hChildStdinWr);
2528
2529 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2530 return win32_error("CreatePipe", NULL);
2531
2532 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002533 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2534 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002535 if (!fSuccess)
2536 return win32_error("DuplicateHandle", NULL);
2537
2538 /* Close the inheritable version of ChildStdout
2539 that we're using. */
2540 CloseHandle(hChildStdoutRd);
2541
2542 if (n != POPEN_4) {
2543 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2544 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002545 fSuccess = DuplicateHandle(GetCurrentProcess(),
2546 hChildStderrRd,
2547 GetCurrentProcess(),
2548 &hChildStderrRdDup, 0,
2549 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002550 if (!fSuccess)
2551 return win32_error("DuplicateHandle", NULL);
2552 /* Close the inheritable version of ChildStdErr that we're using. */
2553 CloseHandle(hChildStderrRd);
2554 }
2555
2556 switch (n) {
2557 case POPEN_1:
2558 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2559 case _O_WRONLY | _O_TEXT:
2560 /* Case for writing to child Stdin in text mode. */
2561 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2562 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002563 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002564 PyFile_SetBufSize(f, 0);
2565 /* We don't care about these pipes anymore, so close them. */
2566 CloseHandle(hChildStdoutRdDup);
2567 CloseHandle(hChildStderrRdDup);
2568 break;
2569
2570 case _O_RDONLY | _O_TEXT:
2571 /* Case for reading from child Stdout in text mode. */
2572 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2573 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002574 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002575 PyFile_SetBufSize(f, 0);
2576 /* We don't care about these pipes anymore, so close them. */
2577 CloseHandle(hChildStdinWrDup);
2578 CloseHandle(hChildStderrRdDup);
2579 break;
2580
2581 case _O_RDONLY | _O_BINARY:
2582 /* Case for readinig from child Stdout in binary mode. */
2583 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2584 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002585 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002586 PyFile_SetBufSize(f, 0);
2587 /* We don't care about these pipes anymore, so close them. */
2588 CloseHandle(hChildStdinWrDup);
2589 CloseHandle(hChildStderrRdDup);
2590 break;
2591
2592 case _O_WRONLY | _O_BINARY:
2593 /* Case for writing to child Stdin in binary mode. */
2594 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2595 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002596 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002597 PyFile_SetBufSize(f, 0);
2598 /* We don't care about these pipes anymore, so close them. */
2599 CloseHandle(hChildStdoutRdDup);
2600 CloseHandle(hChildStderrRdDup);
2601 break;
2602 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002603 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002604 break;
2605
2606 case POPEN_2:
2607 case POPEN_4:
2608 {
2609 char *m1, *m2;
2610 PyObject *p1, *p2;
2611
2612 if (mode && _O_TEXT) {
2613 m1 = "r";
2614 m2 = "w";
2615 } else {
2616 m1 = "rb";
2617 m2 = "wb";
2618 }
2619
2620 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2621 f1 = _fdopen(fd1, m2);
2622 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2623 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002624 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002625 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002626 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002627 PyFile_SetBufSize(p2, 0);
2628
2629 if (n != 4)
2630 CloseHandle(hChildStderrRdDup);
2631
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002632 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002633 Py_XDECREF(p1);
2634 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002635 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002636 break;
2637 }
2638
2639 case POPEN_3:
2640 {
2641 char *m1, *m2;
2642 PyObject *p1, *p2, *p3;
2643
2644 if (mode && _O_TEXT) {
2645 m1 = "r";
2646 m2 = "w";
2647 } else {
2648 m1 = "rb";
2649 m2 = "wb";
2650 }
2651
2652 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2653 f1 = _fdopen(fd1, m2);
2654 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2655 f2 = _fdopen(fd2, m1);
2656 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2657 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002658 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002659 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2660 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002661 PyFile_SetBufSize(p1, 0);
2662 PyFile_SetBufSize(p2, 0);
2663 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002664 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002665 Py_XDECREF(p1);
2666 Py_XDECREF(p2);
2667 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002668 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002669 break;
2670 }
2671 }
2672
2673 if (n == POPEN_4) {
2674 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002675 hChildStdinRd,
2676 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002677 hChildStdoutWr,
2678 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002679 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002680 }
2681 else {
2682 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002683 hChildStdinRd,
2684 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002685 hChildStderrWr,
2686 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002687 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002688 }
2689
Mark Hammondb37a3732000-08-14 04:47:33 +00002690 /*
2691 * Insert the files we've created into the process dictionary
2692 * all referencing the list with the process handle and the
2693 * initial number of files (see description below in _PyPclose).
2694 * Since if _PyPclose later tried to wait on a process when all
2695 * handles weren't closed, it could create a deadlock with the
2696 * child, we spend some energy here to try to ensure that we
2697 * either insert all file handles into the dictionary or none
2698 * at all. It's a little clumsy with the various popen modes
2699 * and variable number of files involved.
2700 */
2701 if (!_PyPopenProcs) {
2702 _PyPopenProcs = PyDict_New();
2703 }
2704
2705 if (_PyPopenProcs) {
2706 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2707 int ins_rc[3];
2708
2709 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2710 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2711
2712 procObj = PyList_New(2);
2713 hProcessObj = PyLong_FromVoidPtr(hProcess);
2714 intObj = PyInt_FromLong(file_count);
2715
2716 if (procObj && hProcessObj && intObj) {
2717 PyList_SetItem(procObj,0,hProcessObj);
2718 PyList_SetItem(procObj,1,intObj);
2719
2720 fileObj[0] = PyLong_FromVoidPtr(f1);
2721 if (fileObj[0]) {
2722 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2723 fileObj[0],
2724 procObj);
2725 }
2726 if (file_count >= 2) {
2727 fileObj[1] = PyLong_FromVoidPtr(f2);
2728 if (fileObj[1]) {
2729 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2730 fileObj[1],
2731 procObj);
2732 }
2733 }
2734 if (file_count >= 3) {
2735 fileObj[2] = PyLong_FromVoidPtr(f3);
2736 if (fileObj[2]) {
2737 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2738 fileObj[2],
2739 procObj);
2740 }
2741 }
2742
2743 if (ins_rc[0] < 0 || !fileObj[0] ||
2744 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2745 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2746 /* Something failed - remove any dictionary
2747 * entries that did make it.
2748 */
2749 if (!ins_rc[0] && fileObj[0]) {
2750 PyDict_DelItem(_PyPopenProcs,
2751 fileObj[0]);
2752 }
2753 if (!ins_rc[1] && fileObj[1]) {
2754 PyDict_DelItem(_PyPopenProcs,
2755 fileObj[1]);
2756 }
2757 if (!ins_rc[2] && fileObj[2]) {
2758 PyDict_DelItem(_PyPopenProcs,
2759 fileObj[2]);
2760 }
2761 }
2762 }
2763
2764 /*
2765 * Clean up our localized references for the dictionary keys
2766 * and value since PyDict_SetItem will Py_INCREF any copies
2767 * that got placed in the dictionary.
2768 */
2769 Py_XDECREF(procObj);
2770 Py_XDECREF(fileObj[0]);
2771 Py_XDECREF(fileObj[1]);
2772 Py_XDECREF(fileObj[2]);
2773 }
2774
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002775 /* Child is launched. Close the parents copy of those pipe
2776 * handles that only the child should have open. You need to
2777 * make sure that no handles to the write end of the output pipe
2778 * are maintained in this process or else the pipe will not close
2779 * when the child process exits and the ReadFile will hang. */
2780
2781 if (!CloseHandle(hChildStdinRd))
2782 return win32_error("CloseHandle", NULL);
2783
2784 if (!CloseHandle(hChildStdoutWr))
2785 return win32_error("CloseHandle", NULL);
2786
2787 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2788 return win32_error("CloseHandle", NULL);
2789
2790 return f;
2791}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002792
2793/*
2794 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2795 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002796 *
2797 * This function uses the _PyPopenProcs dictionary in order to map the
2798 * input file pointer to information about the process that was
2799 * originally created by the popen* call that created the file pointer.
2800 * The dictionary uses the file pointer as a key (with one entry
2801 * inserted for each file returned by the original popen* call) and a
2802 * single list object as the value for all files from a single call.
2803 * The list object contains the Win32 process handle at [0], and a file
2804 * count at [1], which is initialized to the total number of file
2805 * handles using that list.
2806 *
2807 * This function closes whichever handle it is passed, and decrements
2808 * the file count in the dictionary for the process handle pointed to
2809 * by this file. On the last close (when the file count reaches zero),
2810 * this function will wait for the child process and then return its
2811 * exit code as the result of the close() operation. This permits the
2812 * files to be closed in any order - it is always the close() of the
2813 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002814 */
Tim Peters736aa322000-09-01 06:51:24 +00002815
2816 /* RED_FLAG 31-Aug-2000 Tim
2817 * This is always called (today!) between a pair of
2818 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2819 * macros. So the thread running this has no valid thread state, as
2820 * far as Python is concerned. However, this calls some Python API
2821 * functions that cannot be called safely without a valid thread
2822 * state, in particular PyDict_GetItem.
2823 * As a temporary hack (although it may last for years ...), we
2824 * *rely* on not having a valid thread state in this function, in
2825 * order to create our own "from scratch".
2826 * This will deadlock if _PyPclose is ever called by a thread
2827 * holding the global lock.
2828 */
2829
Fredrik Lundh56055a42000-07-23 19:47:12 +00002830static int _PyPclose(FILE *file)
2831{
Fredrik Lundh20318932000-07-26 17:29:12 +00002832 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002833 DWORD exit_code;
2834 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002835 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2836 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002837#ifdef WITH_THREAD
2838 PyInterpreterState* pInterpreterState;
2839 PyThreadState* pThreadState;
2840#endif
2841
Fredrik Lundh20318932000-07-26 17:29:12 +00002842 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002843 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002844 */
2845 result = fclose(file);
2846
Tim Peters736aa322000-09-01 06:51:24 +00002847#ifdef WITH_THREAD
2848 /* Bootstrap a valid thread state into existence. */
2849 pInterpreterState = PyInterpreterState_New();
2850 if (!pInterpreterState) {
2851 /* Well, we're hosed now! We don't have a thread
2852 * state, so can't call a nice error routine, or raise
2853 * an exception. Just die.
2854 */
2855 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002856 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002857 return -1; /* unreachable */
2858 }
2859 pThreadState = PyThreadState_New(pInterpreterState);
2860 if (!pThreadState) {
2861 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002862 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002863 return -1; /* unreachable */
2864 }
2865 /* Grab the global lock. Note that this will deadlock if the
2866 * current thread already has the lock! (see RED_FLAG comments
2867 * before this function)
2868 */
2869 PyEval_RestoreThread(pThreadState);
2870#endif
2871
Fredrik Lundh56055a42000-07-23 19:47:12 +00002872 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002873 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2874 (procObj = PyDict_GetItem(_PyPopenProcs,
2875 fileObj)) != NULL &&
2876 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2877 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2878
2879 hProcess = PyLong_AsVoidPtr(hProcessObj);
2880 file_count = PyInt_AsLong(intObj);
2881
2882 if (file_count > 1) {
2883 /* Still other files referencing process */
2884 file_count--;
2885 PyList_SetItem(procObj,1,
2886 PyInt_FromLong(file_count));
2887 } else {
2888 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002889 if (result != EOF &&
2890 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2891 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002892 /* Possible truncation here in 16-bit environments, but
2893 * real exit codes are just the lower byte in any event.
2894 */
2895 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002896 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002897 /* Indicate failure - this will cause the file object
2898 * to raise an I/O error and translate the last Win32
2899 * error code from errno. We do have a problem with
2900 * last errors that overlap the normal errno table,
2901 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002902 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002903 if (result != EOF) {
2904 /* If the error wasn't from the fclose(), then
2905 * set errno for the file object error handling.
2906 */
2907 errno = GetLastError();
2908 }
2909 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002910 }
2911
2912 /* Free up the native handle at this point */
2913 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002914 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002915
Mark Hammondb37a3732000-08-14 04:47:33 +00002916 /* Remove this file pointer from dictionary */
2917 PyDict_DelItem(_PyPopenProcs, fileObj);
2918
2919 if (PyDict_Size(_PyPopenProcs) == 0) {
2920 Py_DECREF(_PyPopenProcs);
2921 _PyPopenProcs = NULL;
2922 }
2923
2924 } /* if object retrieval ok */
2925
2926 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002927 } /* if _PyPopenProcs */
2928
Tim Peters736aa322000-09-01 06:51:24 +00002929#ifdef WITH_THREAD
2930 /* Tear down the thread & interpreter states.
2931 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002932 * call the thread clear & delete functions, and indeed insist on
2933 * doing that themselves. The lock must be held during the clear, but
2934 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002935 */
2936 PyInterpreterState_Clear(pInterpreterState);
2937 PyEval_ReleaseThread(pThreadState);
2938 PyInterpreterState_Delete(pInterpreterState);
2939#endif
2940
Fredrik Lundh56055a42000-07-23 19:47:12 +00002941 return result;
2942}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002943
2944#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002946posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002947{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002948 char *name;
2949 char *mode = "r";
2950 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002951 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002952 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002953 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002954 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002955 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002956 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002957 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002958 if (fp == NULL)
2959 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002960 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002961 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002962 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002963 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002964}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002965#endif
2966
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002967#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002969
Guido van Rossumb6775db1994-08-01 11:34:53 +00002970#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002971static char posix_setuid__doc__[] =
2972"setuid(uid) -> None\n\
2973Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002974static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002975posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002976{
2977 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002978 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002979 return NULL;
2980 if (setuid(uid) < 0)
2981 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002982 Py_INCREF(Py_None);
2983 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002984}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002985#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002986
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002987
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002988#ifdef HAVE_SETEUID
2989static char posix_seteuid__doc__[] =
2990"seteuid(uid) -> None\n\
2991Set the current process's effective user id.";
2992static PyObject *
2993posix_seteuid (PyObject *self, PyObject *args)
2994{
2995 int euid;
2996 if (!PyArg_ParseTuple(args, "i", &euid)) {
2997 return NULL;
2998 } else if (seteuid(euid) < 0) {
2999 return posix_error();
3000 } else {
3001 Py_INCREF(Py_None);
3002 return Py_None;
3003 }
3004}
3005#endif /* HAVE_SETEUID */
3006
3007#ifdef HAVE_SETEGID
3008static char posix_setegid__doc__[] =
3009"setegid(gid) -> None\n\
3010Set the current process's effective group id.";
3011static PyObject *
3012posix_setegid (PyObject *self, PyObject *args)
3013{
3014 int egid;
3015 if (!PyArg_ParseTuple(args, "i", &egid)) {
3016 return NULL;
3017 } else if (setegid(egid) < 0) {
3018 return posix_error();
3019 } else {
3020 Py_INCREF(Py_None);
3021 return Py_None;
3022 }
3023}
3024#endif /* HAVE_SETEGID */
3025
3026#ifdef HAVE_SETREUID
3027static char posix_setreuid__doc__[] =
3028"seteuid(ruid, euid) -> None\n\
3029Set the current process's real and effective user ids.";
3030static PyObject *
3031posix_setreuid (PyObject *self, PyObject *args)
3032{
3033 int ruid, euid;
3034 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3035 return NULL;
3036 } else if (setreuid(ruid, euid) < 0) {
3037 return posix_error();
3038 } else {
3039 Py_INCREF(Py_None);
3040 return Py_None;
3041 }
3042}
3043#endif /* HAVE_SETREUID */
3044
3045#ifdef HAVE_SETREGID
3046static char posix_setregid__doc__[] =
3047"setegid(rgid, egid) -> None\n\
3048Set the current process's real and effective group ids.";
3049static PyObject *
3050posix_setregid (PyObject *self, PyObject *args)
3051{
3052 int rgid, egid;
3053 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3054 return NULL;
3055 } else if (setregid(rgid, egid) < 0) {
3056 return posix_error();
3057 } else {
3058 Py_INCREF(Py_None);
3059 return Py_None;
3060 }
3061}
3062#endif /* HAVE_SETREGID */
3063
Guido van Rossumb6775db1994-08-01 11:34:53 +00003064#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003065static char posix_setgid__doc__[] =
3066"setgid(gid) -> None\n\
3067Set the current process's group id.";
3068
Barry Warsaw53699e91996-12-10 23:23:01 +00003069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003070posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003071{
3072 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003073 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003074 return NULL;
3075 if (setgid(gid) < 0)
3076 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003077 Py_INCREF(Py_None);
3078 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003079}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003080#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082
Guido van Rossumb6775db1994-08-01 11:34:53 +00003083#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003084static char posix_waitpid__doc__[] =
3085"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003086Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003087
Barry Warsaw53699e91996-12-10 23:23:01 +00003088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003089posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003090{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003091 int pid, options;
3092#ifdef UNION_WAIT
3093 union wait status;
3094#define status_i (status.w_status)
3095#else
3096 int status;
3097#define status_i status
3098#endif
3099 status_i = 0;
3100
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003101 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003102 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003103 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003104#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003105 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003106#else
3107 pid = waitpid(pid, &status, options);
3108#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003109 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003110 if (pid == -1)
3111 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003112 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003113 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003114}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003115#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003116
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003117
Guido van Rossumad0ee831995-03-01 10:34:45 +00003118#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003119static char posix_wait__doc__[] =
3120"wait() -> (pid, status)\n\
3121Wait for completion of a child process.";
3122
Barry Warsaw53699e91996-12-10 23:23:01 +00003123static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003124posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003125{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003126 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003127#ifdef UNION_WAIT
3128 union wait status;
3129#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003130#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003131 int status;
3132#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003133#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003134 if (!PyArg_ParseTuple(args, ":wait"))
3135 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003136 status_i = 0;
3137 Py_BEGIN_ALLOW_THREADS
3138 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003139 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003140 if (pid == -1)
3141 return posix_error();
3142 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003143 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003144#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003145}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003146#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003148
3149static char posix_lstat__doc__[] =
3150"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3151Like stat(path), but do not follow symbolic links.";
3152
Barry Warsaw53699e91996-12-10 23:23:01 +00003153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003154posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003155{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003156#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003157 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003158#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003159 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003160#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003161}
3162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003163
Guido van Rossumb6775db1994-08-01 11:34:53 +00003164#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003165static char posix_readlink__doc__[] =
3166"readlink(path) -> path\n\
3167Return a string representing the path to which the symbolic link points.";
3168
Barry Warsaw53699e91996-12-10 23:23:01 +00003169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003170posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003171{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003172 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003173 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003174 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003175 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003176 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003177 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003178 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003179 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003180 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003181 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003182 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003183}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003184#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003185
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003186
Guido van Rossumb6775db1994-08-01 11:34:53 +00003187#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003188static char posix_symlink__doc__[] =
3189"symlink(src, dst) -> None\n\
3190Create a symbolic link.";
3191
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003193posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003194{
Mark Hammondef8b6542001-05-13 08:04:26 +00003195 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003196}
3197#endif /* HAVE_SYMLINK */
3198
3199
3200#ifdef HAVE_TIMES
3201#ifndef HZ
3202#define HZ 60 /* Universal constant :-) */
3203#endif /* HZ */
3204
Guido van Rossumd48f2521997-12-05 22:19:34 +00003205#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3206static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003207system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003208{
3209 ULONG value = 0;
3210
3211 Py_BEGIN_ALLOW_THREADS
3212 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3213 Py_END_ALLOW_THREADS
3214
3215 return value;
3216}
3217
3218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003219posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003220{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003221 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003222 return NULL;
3223
3224 /* Currently Only Uptime is Provided -- Others Later */
3225 return Py_BuildValue("ddddd",
3226 (double)0 /* t.tms_utime / HZ */,
3227 (double)0 /* t.tms_stime / HZ */,
3228 (double)0 /* t.tms_cutime / HZ */,
3229 (double)0 /* t.tms_cstime / HZ */,
3230 (double)system_uptime() / 1000);
3231}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003232#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003234posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003235{
3236 struct tms t;
3237 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003238 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003239 return NULL;
3240 errno = 0;
3241 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003242 if (c == (clock_t) -1)
3243 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003244 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003245 (double)t.tms_utime / HZ,
3246 (double)t.tms_stime / HZ,
3247 (double)t.tms_cutime / HZ,
3248 (double)t.tms_cstime / HZ,
3249 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003250}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003251#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003252#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003253
3254
Guido van Rossum87755a21996-09-07 00:59:43 +00003255#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003256#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003257static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003258posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003259{
3260 FILETIME create, exit, kernel, user;
3261 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003262 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003263 return NULL;
3264 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003265 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3266 /* The fields of a FILETIME structure are the hi and lo part
3267 of a 64-bit value expressed in 100 nanosecond units.
3268 1e7 is one second in such units; 1e-7 the inverse.
3269 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3270 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003271 return Py_BuildValue(
3272 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003273 (double)(kernel.dwHighDateTime*429.4967296 +
3274 kernel.dwLowDateTime*1e-7),
3275 (double)(user.dwHighDateTime*429.4967296 +
3276 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003277 (double)0,
3278 (double)0,
3279 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003280}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003281#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003282
3283#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003284static char posix_times__doc__[] =
3285"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3286Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003287#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003289
Guido van Rossumb6775db1994-08-01 11:34:53 +00003290#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003291static char posix_setsid__doc__[] =
3292"setsid() -> None\n\
3293Call the system call setsid().";
3294
Barry Warsaw53699e91996-12-10 23:23:01 +00003295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003296posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003297{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003298 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003299 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003300 if (setsid() < 0)
3301 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003302 Py_INCREF(Py_None);
3303 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003304}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003305#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003306
Guido van Rossumb6775db1994-08-01 11:34:53 +00003307#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003308static char posix_setpgid__doc__[] =
3309"setpgid(pid, pgrp) -> None\n\
3310Call the system call setpgid().";
3311
Barry Warsaw53699e91996-12-10 23:23:01 +00003312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003313posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003314{
3315 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003316 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003317 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003318 if (setpgid(pid, pgrp) < 0)
3319 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003320 Py_INCREF(Py_None);
3321 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003322}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003323#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003325
Guido van Rossumb6775db1994-08-01 11:34:53 +00003326#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003327static char posix_tcgetpgrp__doc__[] =
3328"tcgetpgrp(fd) -> pgid\n\
3329Return the process group associated with the terminal given by a fd.";
3330
Barry Warsaw53699e91996-12-10 23:23:01 +00003331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003332posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003333{
3334 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003335 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003336 return NULL;
3337 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003338 if (pgid < 0)
3339 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003340 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003341}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003342#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003344
Guido van Rossumb6775db1994-08-01 11:34:53 +00003345#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003346static char posix_tcsetpgrp__doc__[] =
3347"tcsetpgrp(fd, pgid) -> None\n\
3348Set the process group associated with the terminal given by a fd.";
3349
Barry Warsaw53699e91996-12-10 23:23:01 +00003350static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003351posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003352{
3353 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003354 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003355 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003356 if (tcsetpgrp(fd, pgid) < 0)
3357 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003358 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003359 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003360}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003361#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003362
Guido van Rossum687dd131993-05-17 08:34:16 +00003363/* Functions acting on file descriptors */
3364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003365static char posix_open__doc__[] =
3366"open(filename, flag [, mode=0777]) -> fd\n\
3367Open a file (for low level IO).";
3368
Barry Warsaw53699e91996-12-10 23:23:01 +00003369static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003370posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003371{
Mark Hammondef8b6542001-05-13 08:04:26 +00003372 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003373 int flag;
3374 int mode = 0777;
3375 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003376 if (!PyArg_ParseTuple(args, "eti|i",
3377 Py_FileSystemDefaultEncoding, &file,
3378 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003379 return NULL;
3380
Barry Warsaw53699e91996-12-10 23:23:01 +00003381 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003382 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003383 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003384 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003385 return posix_error_with_allocated_filename(file);
3386 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003387 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003388}
3389
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003390
3391static char posix_close__doc__[] =
3392"close(fd) -> None\n\
3393Close a file descriptor (for low level IO).";
3394
Barry Warsaw53699e91996-12-10 23:23:01 +00003395static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003396posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003397{
3398 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003399 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003400 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003401 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003402 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003403 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003404 if (res < 0)
3405 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003406 Py_INCREF(Py_None);
3407 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003408}
3409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003410
3411static char posix_dup__doc__[] =
3412"dup(fd) -> fd2\n\
3413Return a duplicate of a file descriptor.";
3414
Barry Warsaw53699e91996-12-10 23:23:01 +00003415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003416posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003417{
3418 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003419 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003420 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003421 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003422 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003423 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003424 if (fd < 0)
3425 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003426 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003427}
3428
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003429
3430static char posix_dup2__doc__[] =
3431"dup2(fd, fd2) -> None\n\
3432Duplicate file descriptor.";
3433
Barry Warsaw53699e91996-12-10 23:23:01 +00003434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003435posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003436{
3437 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003438 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003439 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003440 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003441 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003442 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003443 if (res < 0)
3444 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003445 Py_INCREF(Py_None);
3446 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003447}
3448
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003449
3450static char posix_lseek__doc__[] =
3451"lseek(fd, pos, how) -> newpos\n\
3452Set the current position of a file descriptor.";
3453
Barry Warsaw53699e91996-12-10 23:23:01 +00003454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003455posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003456{
3457 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003458#ifdef MS_WIN64
3459 LONG_LONG pos, res;
3460#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003461 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003462#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003463 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003464 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003465 return NULL;
3466#ifdef SEEK_SET
3467 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3468 switch (how) {
3469 case 0: how = SEEK_SET; break;
3470 case 1: how = SEEK_CUR; break;
3471 case 2: how = SEEK_END; break;
3472 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003473#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003474
3475#if !defined(HAVE_LARGEFILE_SUPPORT)
3476 pos = PyInt_AsLong(posobj);
3477#else
3478 pos = PyLong_Check(posobj) ?
3479 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3480#endif
3481 if (PyErr_Occurred())
3482 return NULL;
3483
Barry Warsaw53699e91996-12-10 23:23:01 +00003484 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003485#ifdef MS_WIN64
3486 res = _lseeki64(fd, pos, how);
3487#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003488 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003489#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003490 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003491 if (res < 0)
3492 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003493
3494#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003495 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003496#else
3497 return PyLong_FromLongLong(res);
3498#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003499}
3500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003501
3502static char posix_read__doc__[] =
3503"read(fd, buffersize) -> string\n\
3504Read a file descriptor.";
3505
Barry Warsaw53699e91996-12-10 23:23:01 +00003506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003507posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003508{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003509 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003510 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003511 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003512 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003513 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003514 if (buffer == NULL)
3515 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003516 Py_BEGIN_ALLOW_THREADS
3517 n = read(fd, PyString_AsString(buffer), size);
3518 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003519 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003520 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003521 return posix_error();
3522 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003523 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003524 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003525 return buffer;
3526}
3527
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003528
3529static char posix_write__doc__[] =
3530"write(fd, string) -> byteswritten\n\
3531Write a string to a file descriptor.";
3532
Barry Warsaw53699e91996-12-10 23:23:01 +00003533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003534posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003535{
3536 int fd, size;
3537 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003538 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003539 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003540 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003541 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003542 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003543 if (size < 0)
3544 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003545 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003546}
3547
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003548
3549static char posix_fstat__doc__[]=
3550"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3551Like stat(), but for an open file descriptor.";
3552
Barry Warsaw53699e91996-12-10 23:23:01 +00003553static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003554posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003555{
3556 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003557 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003558 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003559 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003560 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003561 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003562 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003563 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003564 if (res != 0)
3565 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003566
3567 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003568}
3569
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003570
3571static char posix_fdopen__doc__[] =
3572"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3573Return an open file object connected to a file descriptor.";
3574
Barry Warsaw53699e91996-12-10 23:23:01 +00003575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003576posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003577{
Guido van Rossum687dd131993-05-17 08:34:16 +00003578 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003579 char *mode = "r";
3580 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003581 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003582 PyObject *f;
3583 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003584 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003585
Barry Warsaw53699e91996-12-10 23:23:01 +00003586 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003587 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003588 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003589 if (fp == NULL)
3590 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003591 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003592 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003593 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003594 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003595}
3596
Skip Montanaro1517d842000-07-19 14:34:14 +00003597static char posix_isatty__doc__[] =
3598"isatty(fd) -> Boolean\n\
3599Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003600connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003601
3602static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003603posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003604{
3605 int fd;
3606 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3607 return NULL;
3608 return Py_BuildValue("i", isatty(fd));
3609}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003610
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003611#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003612static char posix_pipe__doc__[] =
3613"pipe() -> (read_end, write_end)\n\
3614Create a pipe.";
3615
Barry Warsaw53699e91996-12-10 23:23:01 +00003616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003617posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003618{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003619#if defined(PYOS_OS2)
3620 HFILE read, write;
3621 APIRET rc;
3622
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003623 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003624 return NULL;
3625
3626 Py_BEGIN_ALLOW_THREADS
3627 rc = DosCreatePipe( &read, &write, 4096);
3628 Py_END_ALLOW_THREADS
3629 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003630 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003631
3632 return Py_BuildValue("(ii)", read, write);
3633#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003634#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003635 int fds[2];
3636 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003637 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003638 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003639 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003640 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003641 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003642 if (res != 0)
3643 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003644 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003645#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003646 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003647 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003648 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003649 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003650 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003651 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003652 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003653 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003654 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003655 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003656 read_fd = _open_osfhandle((intptr_t)read, 0);
3657 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003658 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003659#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003660#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003661}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003662#endif /* HAVE_PIPE */
3663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003664
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003665#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003666static char posix_mkfifo__doc__[] =
3667"mkfifo(file, [, mode=0666]) -> None\n\
3668Create a FIFO (a POSIX named pipe).";
3669
Barry Warsaw53699e91996-12-10 23:23:01 +00003670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003671posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003672{
3673 char *file;
3674 int mode = 0666;
3675 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003676 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003677 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003678 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003679 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003680 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003681 if (res < 0)
3682 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003683 Py_INCREF(Py_None);
3684 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003685}
3686#endif
3687
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003688
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003689#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003690static char posix_ftruncate__doc__[] =
3691"ftruncate(fd, length) -> None\n\
3692Truncate a file to a specified length.";
3693
Barry Warsaw53699e91996-12-10 23:23:01 +00003694static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003695posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003696{
3697 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003698 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003699 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003700 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003701
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003702 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003703 return NULL;
3704
3705#if !defined(HAVE_LARGEFILE_SUPPORT)
3706 length = PyInt_AsLong(lenobj);
3707#else
3708 length = PyLong_Check(lenobj) ?
3709 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3710#endif
3711 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003712 return NULL;
3713
Barry Warsaw53699e91996-12-10 23:23:01 +00003714 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003715 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003716 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003717 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003718 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003719 return NULL;
3720 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003721 Py_INCREF(Py_None);
3722 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003723}
3724#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003725
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003726#ifdef NeXT
3727#define HAVE_PUTENV
3728/* Steve Spicklemire got this putenv from NeXTAnswers */
3729static int
3730putenv(char *newval)
3731{
3732 extern char **environ;
3733
3734 static int firstTime = 1;
3735 char **ep;
3736 char *cp;
3737 int esiz;
3738 char *np;
3739
3740 if (!(np = strchr(newval, '=')))
3741 return 1;
3742 *np = '\0';
3743
3744 /* look it up */
3745 for (ep=environ ; *ep ; ep++)
3746 {
3747 /* this should always be true... */
3748 if (cp = strchr(*ep, '='))
3749 {
3750 *cp = '\0';
3751 if (!strcmp(*ep, newval))
3752 {
3753 /* got it! */
3754 *cp = '=';
3755 break;
3756 }
3757 *cp = '=';
3758 }
3759 else
3760 {
3761 *np = '=';
3762 return 1;
3763 }
3764 }
3765
3766 *np = '=';
3767 if (*ep)
3768 {
3769 /* the string was already there:
3770 just replace it with the new one */
3771 *ep = newval;
3772 return 0;
3773 }
3774
3775 /* expand environ by one */
3776 for (esiz=2, ep=environ ; *ep ; ep++)
3777 esiz++;
3778 if (firstTime)
3779 {
3780 char **epp;
3781 char **newenv;
3782 if (!(newenv = malloc(esiz * sizeof(char *))))
3783 return 1;
3784
3785 for (ep=environ, epp=newenv ; *ep ;)
3786 *epp++ = *ep++;
3787 *epp++ = newval;
3788 *epp = (char *) 0;
3789 environ = newenv;
3790 }
3791 else
3792 {
3793 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3794 return 1;
3795 environ[esiz - 2] = newval;
3796 environ[esiz - 1] = (char *) 0;
3797 firstTime = 0;
3798 }
3799
3800 return 0;
3801}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003802#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003803
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003804
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003805#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003806static char posix_putenv__doc__[] =
3807"putenv(key, value) -> None\n\
3808Change or add an environment variable.";
3809
Fred Drake762e2061999-08-26 17:23:54 +00003810/* Save putenv() parameters as values here, so we can collect them when they
3811 * get re-set with another call for the same key. */
3812static PyObject *posix_putenv_garbage;
3813
Barry Warsaw53699e91996-12-10 23:23:01 +00003814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003815posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003816{
3817 char *s1, *s2;
3818 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003819 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003820
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003821 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003822 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003823
3824#if defined(PYOS_OS2)
3825 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3826 APIRET rc;
3827
3828 if (strlen(s2) == 0) /* If New Value is an Empty String */
3829 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3830
3831 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3832 if (rc != NO_ERROR)
3833 return os2_error(rc);
3834
3835 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3836 APIRET rc;
3837
3838 if (strlen(s2) == 0) /* If New Value is an Empty String */
3839 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3840
3841 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3842 if (rc != NO_ERROR)
3843 return os2_error(rc);
3844 } else {
3845#endif
3846
Fred Drake762e2061999-08-26 17:23:54 +00003847 /* XXX This can leak memory -- not easy to fix :-( */
3848 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3849 if (newstr == NULL)
3850 return PyErr_NoMemory();
3851 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003852 (void) sprintf(new, "%s=%s", s1, s2);
3853 if (putenv(new)) {
3854 posix_error();
3855 return NULL;
3856 }
Fred Drake762e2061999-08-26 17:23:54 +00003857 /* Install the first arg and newstr in posix_putenv_garbage;
3858 * this will cause previous value to be collected. This has to
3859 * happen after the real putenv() call because the old value
3860 * was still accessible until then. */
3861 if (PyDict_SetItem(posix_putenv_garbage,
3862 PyTuple_GET_ITEM(args, 0), newstr)) {
3863 /* really not much we can do; just leak */
3864 PyErr_Clear();
3865 }
3866 else {
3867 Py_DECREF(newstr);
3868 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003869
3870#if defined(PYOS_OS2)
3871 }
3872#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003873 Py_INCREF(Py_None);
3874 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003875}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003876#endif /* putenv */
3877
3878#ifdef HAVE_STRERROR
3879static char posix_strerror__doc__[] =
3880"strerror(code) -> string\n\
3881Translate an error code to a message string.";
3882
Guido van Rossumf68d8e52001-04-14 17:55:09 +00003883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003884posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003885{
3886 int code;
3887 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003888 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003889 return NULL;
3890 message = strerror(code);
3891 if (message == NULL) {
3892 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003893 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003894 return NULL;
3895 }
3896 return PyString_FromString(message);
3897}
3898#endif /* strerror */
3899
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003900
Guido van Rossumc9641791998-08-04 15:26:23 +00003901#ifdef HAVE_SYS_WAIT_H
3902
3903#ifdef WIFSTOPPED
3904static char posix_WIFSTOPPED__doc__[] =
3905"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003906Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003907
3908static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003909posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003910{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003911#ifdef UNION_WAIT
3912 union wait status;
3913#define status_i (status.w_status)
3914#else
3915 int status;
3916#define status_i status
3917#endif
3918 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003919
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003920 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003921 {
3922 return NULL;
3923 }
3924
3925 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003926#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003927}
3928#endif /* WIFSTOPPED */
3929
3930#ifdef WIFSIGNALED
3931static char posix_WIFSIGNALED__doc__[] =
3932"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003933Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003934
3935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003936posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003937{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003938#ifdef UNION_WAIT
3939 union wait status;
3940#define status_i (status.w_status)
3941#else
3942 int status;
3943#define status_i status
3944#endif
3945 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003946
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003947 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003948 {
3949 return NULL;
3950 }
3951
3952 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003953#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003954}
3955#endif /* WIFSIGNALED */
3956
3957#ifdef WIFEXITED
3958static char posix_WIFEXITED__doc__[] =
3959"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003960Return true if the process returning 'status' exited using the exit()\n\
3961system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003962
3963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003964posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003965{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003966#ifdef UNION_WAIT
3967 union wait status;
3968#define status_i (status.w_status)
3969#else
3970 int status;
3971#define status_i status
3972#endif
3973 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003974
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003975 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003976 {
3977 return NULL;
3978 }
3979
3980 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003981#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003982}
3983#endif /* WIFEXITED */
3984
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003985#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003986static char posix_WEXITSTATUS__doc__[] =
3987"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003988Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003989
3990static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003991posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003992{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003993#ifdef UNION_WAIT
3994 union wait status;
3995#define status_i (status.w_status)
3996#else
3997 int status;
3998#define status_i status
3999#endif
4000 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004001
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004002 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004003 {
4004 return NULL;
4005 }
4006
4007 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004008#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004009}
4010#endif /* WEXITSTATUS */
4011
4012#ifdef WTERMSIG
4013static char posix_WTERMSIG__doc__[] =
4014"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004015Return the signal that terminated the process that provided the 'status'\n\
4016value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004017
4018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004019posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004020{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004021#ifdef UNION_WAIT
4022 union wait status;
4023#define status_i (status.w_status)
4024#else
4025 int status;
4026#define status_i status
4027#endif
4028 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004029
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004030 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004031 {
4032 return NULL;
4033 }
4034
4035 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004036#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004037}
4038#endif /* WTERMSIG */
4039
4040#ifdef WSTOPSIG
4041static char posix_WSTOPSIG__doc__[] =
4042"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004043Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004044
4045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004046posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004047{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004048#ifdef UNION_WAIT
4049 union wait status;
4050#define status_i (status.w_status)
4051#else
4052 int status;
4053#define status_i status
4054#endif
4055 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004056
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004057 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004058 {
4059 return NULL;
4060 }
4061
4062 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004063#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004064}
4065#endif /* WSTOPSIG */
4066
4067#endif /* HAVE_SYS_WAIT_H */
4068
4069
Guido van Rossum94f6f721999-01-06 18:42:14 +00004070#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004071#ifdef _SCO_DS
4072/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4073 needed definitions in sys/statvfs.h */
4074#define _SVID3
4075#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004076#include <sys/statvfs.h>
4077
4078static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004079"fstatvfs(fd) -> \n\
4080 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004081Perform an fstatvfs system call on the given fd.";
4082
4083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004084posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004085{
4086 int fd, res;
4087 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004088 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004089 return NULL;
4090 Py_BEGIN_ALLOW_THREADS
4091 res = fstatvfs(fd, &st);
4092 Py_END_ALLOW_THREADS
4093 if (res != 0)
4094 return posix_error();
4095#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004096 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004097 (long) st.f_bsize,
4098 (long) st.f_frsize,
4099 (long) st.f_blocks,
4100 (long) st.f_bfree,
4101 (long) st.f_bavail,
4102 (long) st.f_files,
4103 (long) st.f_ffree,
4104 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004105 (long) st.f_flag,
4106 (long) st.f_namemax);
4107#else
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_LONG) st.f_blocks,
4112 (LONG_LONG) st.f_bfree,
4113 (LONG_LONG) st.f_bavail,
4114 (LONG_LONG) st.f_files,
4115 (LONG_LONG) st.f_ffree,
4116 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004117 (long) st.f_flag,
4118 (long) st.f_namemax);
4119#endif
4120}
4121#endif /* HAVE_FSTATVFS */
4122
4123
4124#if defined(HAVE_STATVFS)
4125#include <sys/statvfs.h>
4126
4127static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004128"statvfs(path) -> \n\
4129 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004130Perform a statvfs system call on the given path.";
4131
4132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004133posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004134{
4135 char *path;
4136 int res;
4137 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004138 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004139 return NULL;
4140 Py_BEGIN_ALLOW_THREADS
4141 res = statvfs(path, &st);
4142 Py_END_ALLOW_THREADS
4143 if (res != 0)
4144 return posix_error_with_filename(path);
4145#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004146 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004147 (long) st.f_bsize,
4148 (long) st.f_frsize,
4149 (long) st.f_blocks,
4150 (long) st.f_bfree,
4151 (long) st.f_bavail,
4152 (long) st.f_files,
4153 (long) st.f_ffree,
4154 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004155 (long) st.f_flag,
4156 (long) st.f_namemax);
4157#else /* 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_LONG) st.f_blocks,
4162 (LONG_LONG) st.f_bfree,
4163 (LONG_LONG) st.f_bavail,
4164 (LONG_LONG) st.f_files,
4165 (LONG_LONG) st.f_ffree,
4166 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004167 (long) st.f_flag,
4168 (long) st.f_namemax);
4169#endif
4170}
4171#endif /* HAVE_STATVFS */
4172
4173
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004174#ifdef HAVE_TEMPNAM
4175static char posix_tempnam__doc__[] = "\
4176tempnam([dir[, prefix]]) -> string\n\
4177Return a unique name for a temporary file.\n\
4178The directory and a short may be specified as strings; they may be omitted\n\
4179or None if not needed.";
4180
4181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004182posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004183{
4184 PyObject *result = NULL;
4185 char *dir = NULL;
4186 char *pfx = NULL;
4187 char *name;
4188
4189 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4190 return NULL;
4191 name = tempnam(dir, pfx);
4192 if (name == NULL)
4193 return PyErr_NoMemory();
4194 result = PyString_FromString(name);
4195 free(name);
4196 return result;
4197}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004198#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004199
4200
4201#ifdef HAVE_TMPFILE
4202static char posix_tmpfile__doc__[] = "\
4203tmpfile() -> file object\n\
4204Create a temporary file with no directory entries.";
4205
4206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004207posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004208{
4209 FILE *fp;
4210
4211 if (!PyArg_ParseTuple(args, ":tmpfile"))
4212 return NULL;
4213 fp = tmpfile();
4214 if (fp == NULL)
4215 return posix_error();
4216 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4217}
4218#endif
4219
4220
4221#ifdef HAVE_TMPNAM
4222static char posix_tmpnam__doc__[] = "\
4223tmpnam() -> string\n\
4224Return a unique name for a temporary file.";
4225
4226static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004227posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004228{
4229 char buffer[L_tmpnam];
4230 char *name;
4231
4232 if (!PyArg_ParseTuple(args, ":tmpnam"))
4233 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004234#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004235 name = tmpnam_r(buffer);
4236#else
4237 name = tmpnam(buffer);
4238#endif
4239 if (name == NULL) {
4240 PyErr_SetObject(PyExc_OSError,
4241 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004242#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004243 "unexpected NULL from tmpnam_r"
4244#else
4245 "unexpected NULL from tmpnam"
4246#endif
4247 ));
4248 return NULL;
4249 }
4250 return PyString_FromString(buffer);
4251}
4252#endif
4253
4254
Fred Drakec9680921999-12-13 16:37:25 +00004255/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4256 * It maps strings representing configuration variable names to
4257 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004258 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004259 * rarely-used constants. There are three separate tables that use
4260 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004261 *
4262 * This code is always included, even if none of the interfaces that
4263 * need it are included. The #if hackery needed to avoid it would be
4264 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004265 */
4266struct constdef {
4267 char *name;
4268 long value;
4269};
4270
Fred Drake12c6e2d1999-12-14 21:25:03 +00004271static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004272conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4273 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004274{
4275 if (PyInt_Check(arg)) {
4276 *valuep = PyInt_AS_LONG(arg);
4277 return 1;
4278 }
4279 if (PyString_Check(arg)) {
4280 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004281 size_t lo = 0;
4282 size_t mid;
4283 size_t hi = tablesize;
4284 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004285 char *confname = PyString_AS_STRING(arg);
4286 while (lo < hi) {
4287 mid = (lo + hi) / 2;
4288 cmp = strcmp(confname, table[mid].name);
4289 if (cmp < 0)
4290 hi = mid;
4291 else if (cmp > 0)
4292 lo = mid + 1;
4293 else {
4294 *valuep = table[mid].value;
4295 return 1;
4296 }
4297 }
4298 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4299 }
4300 else
4301 PyErr_SetString(PyExc_TypeError,
4302 "configuration names must be strings or integers");
4303 return 0;
4304}
4305
4306
4307#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4308static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004309#ifdef _PC_ABI_AIO_XFER_MAX
4310 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4311#endif
4312#ifdef _PC_ABI_ASYNC_IO
4313 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4314#endif
Fred Drakec9680921999-12-13 16:37:25 +00004315#ifdef _PC_ASYNC_IO
4316 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4317#endif
4318#ifdef _PC_CHOWN_RESTRICTED
4319 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4320#endif
4321#ifdef _PC_FILESIZEBITS
4322 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4323#endif
4324#ifdef _PC_LAST
4325 {"PC_LAST", _PC_LAST},
4326#endif
4327#ifdef _PC_LINK_MAX
4328 {"PC_LINK_MAX", _PC_LINK_MAX},
4329#endif
4330#ifdef _PC_MAX_CANON
4331 {"PC_MAX_CANON", _PC_MAX_CANON},
4332#endif
4333#ifdef _PC_MAX_INPUT
4334 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4335#endif
4336#ifdef _PC_NAME_MAX
4337 {"PC_NAME_MAX", _PC_NAME_MAX},
4338#endif
4339#ifdef _PC_NO_TRUNC
4340 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4341#endif
4342#ifdef _PC_PATH_MAX
4343 {"PC_PATH_MAX", _PC_PATH_MAX},
4344#endif
4345#ifdef _PC_PIPE_BUF
4346 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4347#endif
4348#ifdef _PC_PRIO_IO
4349 {"PC_PRIO_IO", _PC_PRIO_IO},
4350#endif
4351#ifdef _PC_SOCK_MAXBUF
4352 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4353#endif
4354#ifdef _PC_SYNC_IO
4355 {"PC_SYNC_IO", _PC_SYNC_IO},
4356#endif
4357#ifdef _PC_VDISABLE
4358 {"PC_VDISABLE", _PC_VDISABLE},
4359#endif
4360};
4361
Fred Drakec9680921999-12-13 16:37:25 +00004362static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004363conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004364{
4365 return conv_confname(arg, valuep, posix_constants_pathconf,
4366 sizeof(posix_constants_pathconf)
4367 / sizeof(struct constdef));
4368}
4369#endif
4370
4371#ifdef HAVE_FPATHCONF
4372static char posix_fpathconf__doc__[] = "\
4373fpathconf(fd, name) -> integer\n\
4374Return the configuration limit name for the file descriptor fd.\n\
4375If there is no limit, return -1.";
4376
4377static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004378posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004379{
4380 PyObject *result = NULL;
4381 int name, fd;
4382
Fred Drake12c6e2d1999-12-14 21:25:03 +00004383 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4384 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004385 long limit;
4386
4387 errno = 0;
4388 limit = fpathconf(fd, name);
4389 if (limit == -1 && errno != 0)
4390 posix_error();
4391 else
4392 result = PyInt_FromLong(limit);
4393 }
4394 return result;
4395}
4396#endif
4397
4398
4399#ifdef HAVE_PATHCONF
4400static char posix_pathconf__doc__[] = "\
4401pathconf(path, name) -> integer\n\
4402Return the configuration limit name for the file or directory path.\n\
4403If there is no limit, return -1.";
4404
4405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004406posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004407{
4408 PyObject *result = NULL;
4409 int name;
4410 char *path;
4411
4412 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4413 conv_path_confname, &name)) {
4414 long limit;
4415
4416 errno = 0;
4417 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004418 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004419 if (errno == EINVAL)
4420 /* could be a path or name problem */
4421 posix_error();
4422 else
4423 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004424 }
Fred Drakec9680921999-12-13 16:37:25 +00004425 else
4426 result = PyInt_FromLong(limit);
4427 }
4428 return result;
4429}
4430#endif
4431
4432#ifdef HAVE_CONFSTR
4433static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004434#ifdef _CS_ARCHITECTURE
4435 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4436#endif
4437#ifdef _CS_HOSTNAME
4438 {"CS_HOSTNAME", _CS_HOSTNAME},
4439#endif
4440#ifdef _CS_HW_PROVIDER
4441 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4442#endif
4443#ifdef _CS_HW_SERIAL
4444 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4445#endif
4446#ifdef _CS_INITTAB_NAME
4447 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4448#endif
Fred Drakec9680921999-12-13 16:37:25 +00004449#ifdef _CS_LFS64_CFLAGS
4450 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4451#endif
4452#ifdef _CS_LFS64_LDFLAGS
4453 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4454#endif
4455#ifdef _CS_LFS64_LIBS
4456 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4457#endif
4458#ifdef _CS_LFS64_LINTFLAGS
4459 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4460#endif
4461#ifdef _CS_LFS_CFLAGS
4462 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4463#endif
4464#ifdef _CS_LFS_LDFLAGS
4465 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4466#endif
4467#ifdef _CS_LFS_LIBS
4468 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4469#endif
4470#ifdef _CS_LFS_LINTFLAGS
4471 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4472#endif
Fred Draked86ed291999-12-15 15:34:33 +00004473#ifdef _CS_MACHINE
4474 {"CS_MACHINE", _CS_MACHINE},
4475#endif
Fred Drakec9680921999-12-13 16:37:25 +00004476#ifdef _CS_PATH
4477 {"CS_PATH", _CS_PATH},
4478#endif
Fred Draked86ed291999-12-15 15:34:33 +00004479#ifdef _CS_RELEASE
4480 {"CS_RELEASE", _CS_RELEASE},
4481#endif
4482#ifdef _CS_SRPC_DOMAIN
4483 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4484#endif
4485#ifdef _CS_SYSNAME
4486 {"CS_SYSNAME", _CS_SYSNAME},
4487#endif
4488#ifdef _CS_VERSION
4489 {"CS_VERSION", _CS_VERSION},
4490#endif
Fred Drakec9680921999-12-13 16:37:25 +00004491#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4492 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4493#endif
4494#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4495 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4496#endif
4497#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4498 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4499#endif
4500#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4501 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4502#endif
4503#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4504 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4505#endif
4506#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4507 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4508#endif
4509#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4510 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4511#endif
4512#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4513 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4514#endif
4515#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4516 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4517#endif
4518#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4519 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4520#endif
4521#ifdef _CS_XBS5_LP64_OFF64_LIBS
4522 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4523#endif
4524#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4525 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4526#endif
4527#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4528 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4529#endif
4530#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4531 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4532#endif
4533#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4534 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4535#endif
4536#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4537 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4538#endif
Fred Draked86ed291999-12-15 15:34:33 +00004539#ifdef _MIPS_CS_AVAIL_PROCESSORS
4540 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4541#endif
4542#ifdef _MIPS_CS_BASE
4543 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4544#endif
4545#ifdef _MIPS_CS_HOSTID
4546 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4547#endif
4548#ifdef _MIPS_CS_HW_NAME
4549 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4550#endif
4551#ifdef _MIPS_CS_NUM_PROCESSORS
4552 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4553#endif
4554#ifdef _MIPS_CS_OSREL_MAJ
4555 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4556#endif
4557#ifdef _MIPS_CS_OSREL_MIN
4558 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4559#endif
4560#ifdef _MIPS_CS_OSREL_PATCH
4561 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4562#endif
4563#ifdef _MIPS_CS_OS_NAME
4564 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4565#endif
4566#ifdef _MIPS_CS_OS_PROVIDER
4567 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4568#endif
4569#ifdef _MIPS_CS_PROCESSORS
4570 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4571#endif
4572#ifdef _MIPS_CS_SERIAL
4573 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4574#endif
4575#ifdef _MIPS_CS_VENDOR
4576 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4577#endif
Fred Drakec9680921999-12-13 16:37:25 +00004578};
4579
4580static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004581conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004582{
4583 return conv_confname(arg, valuep, posix_constants_confstr,
4584 sizeof(posix_constants_confstr)
4585 / sizeof(struct constdef));
4586}
4587
4588static char posix_confstr__doc__[] = "\
4589confstr(name) -> string\n\
4590Return a string-valued system configuration variable.";
4591
4592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004593posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004594{
4595 PyObject *result = NULL;
4596 int name;
4597 char buffer[64];
4598
4599 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4600 int len = confstr(name, buffer, sizeof(buffer));
4601
Fred Drakec9680921999-12-13 16:37:25 +00004602 errno = 0;
4603 if (len == 0) {
4604 if (errno != 0)
4605 posix_error();
4606 else
4607 result = PyString_FromString("");
4608 }
4609 else {
4610 if (len >= sizeof(buffer)) {
4611 result = PyString_FromStringAndSize(NULL, len);
4612 if (result != NULL)
4613 confstr(name, PyString_AS_STRING(result), len+1);
4614 }
4615 else
4616 result = PyString_FromString(buffer);
4617 }
4618 }
4619 return result;
4620}
4621#endif
4622
4623
4624#ifdef HAVE_SYSCONF
4625static struct constdef posix_constants_sysconf[] = {
4626#ifdef _SC_2_CHAR_TERM
4627 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4628#endif
4629#ifdef _SC_2_C_BIND
4630 {"SC_2_C_BIND", _SC_2_C_BIND},
4631#endif
4632#ifdef _SC_2_C_DEV
4633 {"SC_2_C_DEV", _SC_2_C_DEV},
4634#endif
4635#ifdef _SC_2_C_VERSION
4636 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4637#endif
4638#ifdef _SC_2_FORT_DEV
4639 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4640#endif
4641#ifdef _SC_2_FORT_RUN
4642 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4643#endif
4644#ifdef _SC_2_LOCALEDEF
4645 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4646#endif
4647#ifdef _SC_2_SW_DEV
4648 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4649#endif
4650#ifdef _SC_2_UPE
4651 {"SC_2_UPE", _SC_2_UPE},
4652#endif
4653#ifdef _SC_2_VERSION
4654 {"SC_2_VERSION", _SC_2_VERSION},
4655#endif
Fred Draked86ed291999-12-15 15:34:33 +00004656#ifdef _SC_ABI_ASYNCHRONOUS_IO
4657 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4658#endif
4659#ifdef _SC_ACL
4660 {"SC_ACL", _SC_ACL},
4661#endif
Fred Drakec9680921999-12-13 16:37:25 +00004662#ifdef _SC_AIO_LISTIO_MAX
4663 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4664#endif
Fred Drakec9680921999-12-13 16:37:25 +00004665#ifdef _SC_AIO_MAX
4666 {"SC_AIO_MAX", _SC_AIO_MAX},
4667#endif
4668#ifdef _SC_AIO_PRIO_DELTA_MAX
4669 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4670#endif
4671#ifdef _SC_ARG_MAX
4672 {"SC_ARG_MAX", _SC_ARG_MAX},
4673#endif
4674#ifdef _SC_ASYNCHRONOUS_IO
4675 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4676#endif
4677#ifdef _SC_ATEXIT_MAX
4678 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4679#endif
Fred Draked86ed291999-12-15 15:34:33 +00004680#ifdef _SC_AUDIT
4681 {"SC_AUDIT", _SC_AUDIT},
4682#endif
Fred Drakec9680921999-12-13 16:37:25 +00004683#ifdef _SC_AVPHYS_PAGES
4684 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4685#endif
4686#ifdef _SC_BC_BASE_MAX
4687 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4688#endif
4689#ifdef _SC_BC_DIM_MAX
4690 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4691#endif
4692#ifdef _SC_BC_SCALE_MAX
4693 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4694#endif
4695#ifdef _SC_BC_STRING_MAX
4696 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4697#endif
Fred Draked86ed291999-12-15 15:34:33 +00004698#ifdef _SC_CAP
4699 {"SC_CAP", _SC_CAP},
4700#endif
Fred Drakec9680921999-12-13 16:37:25 +00004701#ifdef _SC_CHARCLASS_NAME_MAX
4702 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4703#endif
4704#ifdef _SC_CHAR_BIT
4705 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4706#endif
4707#ifdef _SC_CHAR_MAX
4708 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4709#endif
4710#ifdef _SC_CHAR_MIN
4711 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4712#endif
4713#ifdef _SC_CHILD_MAX
4714 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4715#endif
4716#ifdef _SC_CLK_TCK
4717 {"SC_CLK_TCK", _SC_CLK_TCK},
4718#endif
4719#ifdef _SC_COHER_BLKSZ
4720 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4721#endif
4722#ifdef _SC_COLL_WEIGHTS_MAX
4723 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4724#endif
4725#ifdef _SC_DCACHE_ASSOC
4726 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4727#endif
4728#ifdef _SC_DCACHE_BLKSZ
4729 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4730#endif
4731#ifdef _SC_DCACHE_LINESZ
4732 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4733#endif
4734#ifdef _SC_DCACHE_SZ
4735 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4736#endif
4737#ifdef _SC_DCACHE_TBLKSZ
4738 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4739#endif
4740#ifdef _SC_DELAYTIMER_MAX
4741 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4742#endif
4743#ifdef _SC_EQUIV_CLASS_MAX
4744 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4745#endif
4746#ifdef _SC_EXPR_NEST_MAX
4747 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4748#endif
4749#ifdef _SC_FSYNC
4750 {"SC_FSYNC", _SC_FSYNC},
4751#endif
4752#ifdef _SC_GETGR_R_SIZE_MAX
4753 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4754#endif
4755#ifdef _SC_GETPW_R_SIZE_MAX
4756 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4757#endif
4758#ifdef _SC_ICACHE_ASSOC
4759 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4760#endif
4761#ifdef _SC_ICACHE_BLKSZ
4762 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4763#endif
4764#ifdef _SC_ICACHE_LINESZ
4765 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4766#endif
4767#ifdef _SC_ICACHE_SZ
4768 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4769#endif
Fred Draked86ed291999-12-15 15:34:33 +00004770#ifdef _SC_INF
4771 {"SC_INF", _SC_INF},
4772#endif
Fred Drakec9680921999-12-13 16:37:25 +00004773#ifdef _SC_INT_MAX
4774 {"SC_INT_MAX", _SC_INT_MAX},
4775#endif
4776#ifdef _SC_INT_MIN
4777 {"SC_INT_MIN", _SC_INT_MIN},
4778#endif
4779#ifdef _SC_IOV_MAX
4780 {"SC_IOV_MAX", _SC_IOV_MAX},
4781#endif
Fred Draked86ed291999-12-15 15:34:33 +00004782#ifdef _SC_IP_SECOPTS
4783 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4784#endif
Fred Drakec9680921999-12-13 16:37:25 +00004785#ifdef _SC_JOB_CONTROL
4786 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4787#endif
Fred Draked86ed291999-12-15 15:34:33 +00004788#ifdef _SC_KERN_POINTERS
4789 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4790#endif
4791#ifdef _SC_KERN_SIM
4792 {"SC_KERN_SIM", _SC_KERN_SIM},
4793#endif
Fred Drakec9680921999-12-13 16:37:25 +00004794#ifdef _SC_LINE_MAX
4795 {"SC_LINE_MAX", _SC_LINE_MAX},
4796#endif
4797#ifdef _SC_LOGIN_NAME_MAX
4798 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4799#endif
4800#ifdef _SC_LOGNAME_MAX
4801 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4802#endif
4803#ifdef _SC_LONG_BIT
4804 {"SC_LONG_BIT", _SC_LONG_BIT},
4805#endif
Fred Draked86ed291999-12-15 15:34:33 +00004806#ifdef _SC_MAC
4807 {"SC_MAC", _SC_MAC},
4808#endif
Fred Drakec9680921999-12-13 16:37:25 +00004809#ifdef _SC_MAPPED_FILES
4810 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4811#endif
4812#ifdef _SC_MAXPID
4813 {"SC_MAXPID", _SC_MAXPID},
4814#endif
4815#ifdef _SC_MB_LEN_MAX
4816 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4817#endif
4818#ifdef _SC_MEMLOCK
4819 {"SC_MEMLOCK", _SC_MEMLOCK},
4820#endif
4821#ifdef _SC_MEMLOCK_RANGE
4822 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4823#endif
4824#ifdef _SC_MEMORY_PROTECTION
4825 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4826#endif
4827#ifdef _SC_MESSAGE_PASSING
4828 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4829#endif
Fred Draked86ed291999-12-15 15:34:33 +00004830#ifdef _SC_MMAP_FIXED_ALIGNMENT
4831 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4832#endif
Fred Drakec9680921999-12-13 16:37:25 +00004833#ifdef _SC_MQ_OPEN_MAX
4834 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4835#endif
4836#ifdef _SC_MQ_PRIO_MAX
4837 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4838#endif
Fred Draked86ed291999-12-15 15:34:33 +00004839#ifdef _SC_NACLS_MAX
4840 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4841#endif
Fred Drakec9680921999-12-13 16:37:25 +00004842#ifdef _SC_NGROUPS_MAX
4843 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4844#endif
4845#ifdef _SC_NL_ARGMAX
4846 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4847#endif
4848#ifdef _SC_NL_LANGMAX
4849 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4850#endif
4851#ifdef _SC_NL_MSGMAX
4852 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4853#endif
4854#ifdef _SC_NL_NMAX
4855 {"SC_NL_NMAX", _SC_NL_NMAX},
4856#endif
4857#ifdef _SC_NL_SETMAX
4858 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4859#endif
4860#ifdef _SC_NL_TEXTMAX
4861 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4862#endif
4863#ifdef _SC_NPROCESSORS_CONF
4864 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4865#endif
4866#ifdef _SC_NPROCESSORS_ONLN
4867 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4868#endif
Fred Draked86ed291999-12-15 15:34:33 +00004869#ifdef _SC_NPROC_CONF
4870 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4871#endif
4872#ifdef _SC_NPROC_ONLN
4873 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4874#endif
Fred Drakec9680921999-12-13 16:37:25 +00004875#ifdef _SC_NZERO
4876 {"SC_NZERO", _SC_NZERO},
4877#endif
4878#ifdef _SC_OPEN_MAX
4879 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4880#endif
4881#ifdef _SC_PAGESIZE
4882 {"SC_PAGESIZE", _SC_PAGESIZE},
4883#endif
4884#ifdef _SC_PAGE_SIZE
4885 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4886#endif
4887#ifdef _SC_PASS_MAX
4888 {"SC_PASS_MAX", _SC_PASS_MAX},
4889#endif
4890#ifdef _SC_PHYS_PAGES
4891 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4892#endif
4893#ifdef _SC_PII
4894 {"SC_PII", _SC_PII},
4895#endif
4896#ifdef _SC_PII_INTERNET
4897 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4898#endif
4899#ifdef _SC_PII_INTERNET_DGRAM
4900 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4901#endif
4902#ifdef _SC_PII_INTERNET_STREAM
4903 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4904#endif
4905#ifdef _SC_PII_OSI
4906 {"SC_PII_OSI", _SC_PII_OSI},
4907#endif
4908#ifdef _SC_PII_OSI_CLTS
4909 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4910#endif
4911#ifdef _SC_PII_OSI_COTS
4912 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4913#endif
4914#ifdef _SC_PII_OSI_M
4915 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4916#endif
4917#ifdef _SC_PII_SOCKET
4918 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4919#endif
4920#ifdef _SC_PII_XTI
4921 {"SC_PII_XTI", _SC_PII_XTI},
4922#endif
4923#ifdef _SC_POLL
4924 {"SC_POLL", _SC_POLL},
4925#endif
4926#ifdef _SC_PRIORITIZED_IO
4927 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4928#endif
4929#ifdef _SC_PRIORITY_SCHEDULING
4930 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4931#endif
4932#ifdef _SC_REALTIME_SIGNALS
4933 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4934#endif
4935#ifdef _SC_RE_DUP_MAX
4936 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4937#endif
4938#ifdef _SC_RTSIG_MAX
4939 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4940#endif
4941#ifdef _SC_SAVED_IDS
4942 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4943#endif
4944#ifdef _SC_SCHAR_MAX
4945 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4946#endif
4947#ifdef _SC_SCHAR_MIN
4948 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4949#endif
4950#ifdef _SC_SELECT
4951 {"SC_SELECT", _SC_SELECT},
4952#endif
4953#ifdef _SC_SEMAPHORES
4954 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4955#endif
4956#ifdef _SC_SEM_NSEMS_MAX
4957 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4958#endif
4959#ifdef _SC_SEM_VALUE_MAX
4960 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4961#endif
4962#ifdef _SC_SHARED_MEMORY_OBJECTS
4963 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4964#endif
4965#ifdef _SC_SHRT_MAX
4966 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4967#endif
4968#ifdef _SC_SHRT_MIN
4969 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4970#endif
4971#ifdef _SC_SIGQUEUE_MAX
4972 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4973#endif
4974#ifdef _SC_SIGRT_MAX
4975 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4976#endif
4977#ifdef _SC_SIGRT_MIN
4978 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4979#endif
Fred Draked86ed291999-12-15 15:34:33 +00004980#ifdef _SC_SOFTPOWER
4981 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4982#endif
Fred Drakec9680921999-12-13 16:37:25 +00004983#ifdef _SC_SPLIT_CACHE
4984 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4985#endif
4986#ifdef _SC_SSIZE_MAX
4987 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4988#endif
4989#ifdef _SC_STACK_PROT
4990 {"SC_STACK_PROT", _SC_STACK_PROT},
4991#endif
4992#ifdef _SC_STREAM_MAX
4993 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4994#endif
4995#ifdef _SC_SYNCHRONIZED_IO
4996 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4997#endif
4998#ifdef _SC_THREADS
4999 {"SC_THREADS", _SC_THREADS},
5000#endif
5001#ifdef _SC_THREAD_ATTR_STACKADDR
5002 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5003#endif
5004#ifdef _SC_THREAD_ATTR_STACKSIZE
5005 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5006#endif
5007#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5008 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5009#endif
5010#ifdef _SC_THREAD_KEYS_MAX
5011 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5012#endif
5013#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5014 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5015#endif
5016#ifdef _SC_THREAD_PRIO_INHERIT
5017 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5018#endif
5019#ifdef _SC_THREAD_PRIO_PROTECT
5020 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5021#endif
5022#ifdef _SC_THREAD_PROCESS_SHARED
5023 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5024#endif
5025#ifdef _SC_THREAD_SAFE_FUNCTIONS
5026 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5027#endif
5028#ifdef _SC_THREAD_STACK_MIN
5029 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5030#endif
5031#ifdef _SC_THREAD_THREADS_MAX
5032 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5033#endif
5034#ifdef _SC_TIMERS
5035 {"SC_TIMERS", _SC_TIMERS},
5036#endif
5037#ifdef _SC_TIMER_MAX
5038 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5039#endif
5040#ifdef _SC_TTY_NAME_MAX
5041 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5042#endif
5043#ifdef _SC_TZNAME_MAX
5044 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5045#endif
5046#ifdef _SC_T_IOV_MAX
5047 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5048#endif
5049#ifdef _SC_UCHAR_MAX
5050 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5051#endif
5052#ifdef _SC_UINT_MAX
5053 {"SC_UINT_MAX", _SC_UINT_MAX},
5054#endif
5055#ifdef _SC_UIO_MAXIOV
5056 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5057#endif
5058#ifdef _SC_ULONG_MAX
5059 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5060#endif
5061#ifdef _SC_USHRT_MAX
5062 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5063#endif
5064#ifdef _SC_VERSION
5065 {"SC_VERSION", _SC_VERSION},
5066#endif
5067#ifdef _SC_WORD_BIT
5068 {"SC_WORD_BIT", _SC_WORD_BIT},
5069#endif
5070#ifdef _SC_XBS5_ILP32_OFF32
5071 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5072#endif
5073#ifdef _SC_XBS5_ILP32_OFFBIG
5074 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5075#endif
5076#ifdef _SC_XBS5_LP64_OFF64
5077 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5078#endif
5079#ifdef _SC_XBS5_LPBIG_OFFBIG
5080 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5081#endif
5082#ifdef _SC_XOPEN_CRYPT
5083 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5084#endif
5085#ifdef _SC_XOPEN_ENH_I18N
5086 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5087#endif
5088#ifdef _SC_XOPEN_LEGACY
5089 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5090#endif
5091#ifdef _SC_XOPEN_REALTIME
5092 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5093#endif
5094#ifdef _SC_XOPEN_REALTIME_THREADS
5095 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5096#endif
5097#ifdef _SC_XOPEN_SHM
5098 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5099#endif
5100#ifdef _SC_XOPEN_UNIX
5101 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5102#endif
5103#ifdef _SC_XOPEN_VERSION
5104 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5105#endif
5106#ifdef _SC_XOPEN_XCU_VERSION
5107 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5108#endif
5109#ifdef _SC_XOPEN_XPG2
5110 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5111#endif
5112#ifdef _SC_XOPEN_XPG3
5113 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5114#endif
5115#ifdef _SC_XOPEN_XPG4
5116 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5117#endif
5118};
5119
5120static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005121conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005122{
5123 return conv_confname(arg, valuep, posix_constants_sysconf,
5124 sizeof(posix_constants_sysconf)
5125 / sizeof(struct constdef));
5126}
5127
5128static char posix_sysconf__doc__[] = "\
5129sysconf(name) -> integer\n\
5130Return an integer-valued system configuration variable.";
5131
5132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005133posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005134{
5135 PyObject *result = NULL;
5136 int name;
5137
5138 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5139 int value;
5140
5141 errno = 0;
5142 value = sysconf(name);
5143 if (value == -1 && errno != 0)
5144 posix_error();
5145 else
5146 result = PyInt_FromLong(value);
5147 }
5148 return result;
5149}
5150#endif
5151
5152
Fred Drakebec628d1999-12-15 18:31:10 +00005153/* This code is used to ensure that the tables of configuration value names
5154 * are in sorted order as required by conv_confname(), and also to build the
5155 * the exported dictionaries that are used to publish information about the
5156 * names available on the host platform.
5157 *
5158 * Sorting the table at runtime ensures that the table is properly ordered
5159 * when used, even for platforms we're not able to test on. It also makes
5160 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005161 */
Fred Drakebec628d1999-12-15 18:31:10 +00005162
5163static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005164cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005165{
5166 const struct constdef *c1 =
5167 (const struct constdef *) v1;
5168 const struct constdef *c2 =
5169 (const struct constdef *) v2;
5170
5171 return strcmp(c1->name, c2->name);
5172}
5173
5174static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005175setup_confname_table(struct constdef *table, size_t tablesize,
5176 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005177{
Fred Drakebec628d1999-12-15 18:31:10 +00005178 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005179 size_t i;
5180 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005181
5182 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5183 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005184 if (d == NULL)
5185 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005186
Barry Warsaw3155db32000-04-13 15:20:40 +00005187 for (i=0; i < tablesize; ++i) {
5188 PyObject *o = PyInt_FromLong(table[i].value);
5189 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5190 Py_XDECREF(o);
5191 Py_DECREF(d);
5192 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005193 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005194 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005195 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005196 status = PyDict_SetItemString(moddict, tablename, d);
5197 Py_DECREF(d);
5198 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005199}
5200
Fred Drakebec628d1999-12-15 18:31:10 +00005201/* Return -1 on failure, 0 on success. */
5202static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005203setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005204{
5205#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005206 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005207 sizeof(posix_constants_pathconf)
5208 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005209 "pathconf_names", moddict))
5210 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005211#endif
5212#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005213 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005214 sizeof(posix_constants_confstr)
5215 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005216 "confstr_names", moddict))
5217 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005218#endif
5219#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005220 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005221 sizeof(posix_constants_sysconf)
5222 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005223 "sysconf_names", moddict))
5224 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005225#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005226 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005227}
Fred Draked86ed291999-12-15 15:34:33 +00005228
5229
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005230static char posix_abort__doc__[] = "\
5231abort() -> does not return!\n\
5232Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5233in the hardest way possible on the hosting operating system.";
5234
5235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005236posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005237{
5238 if (!PyArg_ParseTuple(args, ":abort"))
5239 return NULL;
5240 abort();
5241 /*NOTREACHED*/
5242 Py_FatalError("abort() called from Python code didn't abort!");
5243 return NULL;
5244}
Fred Drakebec628d1999-12-15 18:31:10 +00005245
Tim Petersf58a7aa2000-09-22 10:05:54 +00005246#ifdef MS_WIN32
5247static char win32_startfile__doc__[] = "\
5248startfile(filepath) - Start a file with its associated application.\n\
5249\n\
5250This acts like double-clicking the file in Explorer, or giving the file\n\
5251name as an argument to the DOS \"start\" command: the file is opened\n\
5252with whatever application (if any) its extension is associated.\n\
5253\n\
5254startfile returns as soon as the associated application is launched.\n\
5255There is no option to wait for the application to close, and no way\n\
5256to retrieve the application's exit status.\n\
5257\n\
5258The filepath is relative to the current directory. If you want to use\n\
5259an absolute path, make sure the first character is not a slash (\"/\");\n\
5260the underlying Win32 ShellExecute function doesn't work if it is.";
5261
5262static PyObject *
5263win32_startfile(PyObject *self, PyObject *args)
5264{
5265 char *filepath;
5266 HINSTANCE rc;
5267 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5268 return NULL;
5269 Py_BEGIN_ALLOW_THREADS
5270 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5271 Py_END_ALLOW_THREADS
5272 if (rc <= (HINSTANCE)32)
5273 return win32_error("startfile", filepath);
5274 Py_INCREF(Py_None);
5275 return Py_None;
5276}
5277#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005278
5279static PyMethodDef posix_methods[] = {
5280 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5281#ifdef HAVE_TTYNAME
5282 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5283#endif
5284 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5285 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005286#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005287 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005288#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005289#ifdef HAVE_CTERMID
5290 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5291#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005292#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005293 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005294#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005295#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005296 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005297#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005298 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5299 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5300 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005301#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005302 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005303#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005304#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005305 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005306#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005307 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5308 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5309 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005310#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005311 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005312#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005313#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005314 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005315#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005316 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005317#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005318 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005319#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005320 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5321 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5322 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005323#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005324 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005325#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005326 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005327#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005328 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5329 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005330#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005331#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005332 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5333 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005334#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005335#ifdef HAVE_FORK1
5336 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5337#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005338#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005339 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005340#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005341#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005342 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005343#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005344#ifdef HAVE_FORKPTY
5345 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5346#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005347#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005348 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005349#endif /* HAVE_GETEGID */
5350#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005351 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005352#endif /* HAVE_GETEUID */
5353#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005354 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005355#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005356#ifdef HAVE_GETGROUPS
5357 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5358#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005359 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005360#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005361 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005362#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005363#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005364 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005365#endif /* HAVE_GETPPID */
5366#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005367 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005368#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005369#ifdef HAVE_GETLOGIN
5370 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5371#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005372#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005373 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005374#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005375#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005376 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005377#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005378#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005379 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005380#ifdef MS_WIN32
5381 {"popen2", win32_popen2, METH_VARARGS},
5382 {"popen3", win32_popen3, METH_VARARGS},
5383 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005384 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005385#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005386#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005387#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005388 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005389#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005390#ifdef HAVE_SETEUID
5391 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5392#endif /* HAVE_SETEUID */
5393#ifdef HAVE_SETEGID
5394 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5395#endif /* HAVE_SETEGID */
5396#ifdef HAVE_SETREUID
5397 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5398#endif /* HAVE_SETREUID */
5399#ifdef HAVE_SETREGID
5400 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5401#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005402#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005403 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005404#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005405#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005406 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005407#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005408#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005409 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005410#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005411#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005412 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005413#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005414#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005415 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005416#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005417#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005418 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005419#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005420#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005421 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005422#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005423#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005424 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005425#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005426 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5427 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5428 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5429 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5430 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5431 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5432 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5433 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5434 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005435 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005436#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005437 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005438#endif
5439#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005440 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005441#endif
5442#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005443 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005444#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005445#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005446 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005447#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005448#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005449 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005450#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005451#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005452 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005453#endif
5454#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005455 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005456#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005457#ifdef HAVE_SYS_WAIT_H
5458#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005459 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005460#endif /* WIFSTOPPED */
5461#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005462 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005463#endif /* WIFSIGNALED */
5464#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005465 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005466#endif /* WIFEXITED */
5467#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005468 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005469#endif /* WEXITSTATUS */
5470#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005471 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005472#endif /* WTERMSIG */
5473#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005474 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005475#endif /* WSTOPSIG */
5476#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005477#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005478 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005479#endif
5480#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005481 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005482#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005483#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005484 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5485#endif
5486#ifdef HAVE_TEMPNAM
5487 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5488#endif
5489#ifdef HAVE_TMPNAM
5490 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5491#endif
Fred Drakec9680921999-12-13 16:37:25 +00005492#ifdef HAVE_CONFSTR
5493 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5494#endif
5495#ifdef HAVE_SYSCONF
5496 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5497#endif
5498#ifdef HAVE_FPATHCONF
5499 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5500#endif
5501#ifdef HAVE_PATHCONF
5502 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5503#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005504 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005505#ifdef MS_WIN32
5506 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5507#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005508 {NULL, NULL} /* Sentinel */
5509};
5510
5511
Barry Warsaw4a342091996-12-19 23:50:02 +00005512static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005513ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005514{
5515 PyObject* v = PyInt_FromLong(value);
5516 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5517 return -1; /* triggers fatal error */
5518
5519 Py_DECREF(v);
5520 return 0;
5521}
5522
Guido van Rossumd48f2521997-12-05 22:19:34 +00005523#if defined(PYOS_OS2)
5524/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5525static int insertvalues(PyObject *d)
5526{
5527 APIRET rc;
5528 ULONG values[QSV_MAX+1];
5529 PyObject *v;
5530 char *ver, tmp[10];
5531
5532 Py_BEGIN_ALLOW_THREADS
5533 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5534 Py_END_ALLOW_THREADS
5535
5536 if (rc != NO_ERROR) {
5537 os2_error(rc);
5538 return -1;
5539 }
5540
5541 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5542 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5543 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5544 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5545 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5546 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5547 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5548
5549 switch (values[QSV_VERSION_MINOR]) {
5550 case 0: ver = "2.00"; break;
5551 case 10: ver = "2.10"; break;
5552 case 11: ver = "2.11"; break;
5553 case 30: ver = "3.00"; break;
5554 case 40: ver = "4.00"; break;
5555 case 50: ver = "5.00"; break;
5556 default:
5557 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5558 values[QSV_VERSION_MINOR]);
5559 ver = &tmp[0];
5560 }
5561
5562 /* Add Indicator of the Version of the Operating System */
5563 v = PyString_FromString(ver);
5564 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5565 return -1;
5566 Py_DECREF(v);
5567
5568 /* Add Indicator of Which Drive was Used to Boot the System */
5569 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5570 tmp[1] = ':';
5571 tmp[2] = '\0';
5572
5573 v = PyString_FromString(tmp);
5574 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5575 return -1;
5576 Py_DECREF(v);
5577
5578 return 0;
5579}
5580#endif
5581
Barry Warsaw4a342091996-12-19 23:50:02 +00005582static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005583all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005584{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005585#ifdef F_OK
5586 if (ins(d, "F_OK", (long)F_OK)) return -1;
5587#endif
5588#ifdef R_OK
5589 if (ins(d, "R_OK", (long)R_OK)) return -1;
5590#endif
5591#ifdef W_OK
5592 if (ins(d, "W_OK", (long)W_OK)) return -1;
5593#endif
5594#ifdef X_OK
5595 if (ins(d, "X_OK", (long)X_OK)) return -1;
5596#endif
Fred Drakec9680921999-12-13 16:37:25 +00005597#ifdef NGROUPS_MAX
5598 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5599#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005600#ifdef TMP_MAX
5601 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5602#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005603#ifdef WNOHANG
5604 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5605#endif
5606#ifdef O_RDONLY
5607 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5608#endif
5609#ifdef O_WRONLY
5610 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5611#endif
5612#ifdef O_RDWR
5613 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5614#endif
5615#ifdef O_NDELAY
5616 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5617#endif
5618#ifdef O_NONBLOCK
5619 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5620#endif
5621#ifdef O_APPEND
5622 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5623#endif
5624#ifdef O_DSYNC
5625 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5626#endif
5627#ifdef O_RSYNC
5628 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5629#endif
5630#ifdef O_SYNC
5631 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5632#endif
5633#ifdef O_NOCTTY
5634 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5635#endif
5636#ifdef O_CREAT
5637 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5638#endif
5639#ifdef O_EXCL
5640 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5641#endif
5642#ifdef O_TRUNC
5643 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5644#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005645#ifdef O_BINARY
5646 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5647#endif
5648#ifdef O_TEXT
5649 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5650#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005651
Guido van Rossum246bc171999-02-01 23:54:31 +00005652#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005653 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5654 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5655 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5656 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5657 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005658#endif
5659
Guido van Rossumd48f2521997-12-05 22:19:34 +00005660#if defined(PYOS_OS2)
5661 if (insertvalues(d)) return -1;
5662#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005663 return 0;
5664}
5665
5666
Tim Peters58e0a8c2001-05-14 22:32:33 +00005667#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005668#define INITFUNC initnt
5669#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005670
5671#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005672#define INITFUNC initos2
5673#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005674
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005675#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005676#define INITFUNC initposix
5677#define MODNAME "posix"
5678#endif
5679
Guido van Rossum3886bb61998-12-04 18:50:17 +00005680DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005681INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005682{
Barry Warsaw53699e91996-12-10 23:23:01 +00005683 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005684
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005685 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005686 posix_methods,
5687 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005688 (PyObject *)NULL,
5689 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005690 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005691
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005692 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005693 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005694 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005695 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005696 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005697
Barry Warsaw4a342091996-12-19 23:50:02 +00005698 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005699 return;
5700
Fred Drakebec628d1999-12-15 18:31:10 +00005701 if (setup_confname_tables(d))
5702 return;
5703
Barry Warsawca74da41999-02-09 19:31:45 +00005704 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005705
Guido van Rossumb3d39562000-01-31 18:41:26 +00005706#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005707 if (posix_putenv_garbage == NULL)
5708 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005709#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005710}