blob: 120c848bfb5f975b280da90b1f9e9f86d4fd5c65 [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;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001124
1125 /* There are two flavours of 'nice': one that returns the new
1126 priority (as required by almost all standards out there) and the
1127 Linux one, which returns '0' on success and advices the use of
1128 getpriority() to get the new priority.
1129
1130 If we are of the nice family that returns the new priority, we
1131 need to clear errno before the call, and check if errno is filled
1132 before calling posix_error() on a returnvalue of -1, because the
1133 -1 may be the actual new priority! */
1134
1135 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001136 value = nice(increment);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001137#ifdef HAVE_GETPRIORITY
1138 if (value == 0)
1139 value = getpriority(PRIO_PROCESS, 0);
1140#endif
1141 if (value == -1 && errno != 0)
1142 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001143 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001144 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001145}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001146#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001148
1149static char posix_rename__doc__[] =
1150"rename(old, new) -> None\n\
1151Rename a file or directory.";
1152
Barry Warsaw53699e91996-12-10 23:23:01 +00001153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001154posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155{
Mark Hammondef8b6542001-05-13 08:04:26 +00001156 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001157}
1158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001159
1160static char posix_rmdir__doc__[] =
1161"rmdir(path) -> None\n\
1162Remove a directory.";
1163
Barry Warsaw53699e91996-12-10 23:23:01 +00001164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001165posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001166{
Mark Hammondef8b6542001-05-13 08:04:26 +00001167 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168}
1169
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001170
1171static char posix_stat__doc__[] =
1172"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1173Perform a stat system call on the given path.";
1174
Barry Warsaw53699e91996-12-10 23:23:01 +00001175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001176posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001177{
Mark Hammondef8b6542001-05-13 08:04:26 +00001178 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001179}
1180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001181
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001182#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001183static char posix_system__doc__[] =
1184"system(command) -> exit_status\n\
1185Execute the command (a string) in a subshell.";
1186
Barry Warsaw53699e91996-12-10 23:23:01 +00001187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001188posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001190 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001191 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001192 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001193 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001194 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001195 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001196 Py_END_ALLOW_THREADS
1197 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001198}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001199#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001201
1202static char posix_umask__doc__[] =
1203"umask(new_mask) -> old_mask\n\
1204Set the current numeric umask and return the previous umask.";
1205
Barry Warsaw53699e91996-12-10 23:23:01 +00001206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001207posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001208{
1209 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001210 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211 return NULL;
1212 i = umask(i);
1213 if (i < 0)
1214 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001215 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001216}
1217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001218
1219static char posix_unlink__doc__[] =
1220"unlink(path) -> None\n\
1221Remove a file (same as remove(path)).";
1222
1223static char posix_remove__doc__[] =
1224"remove(path) -> None\n\
1225Remove a file (same as unlink(path)).";
1226
Barry Warsaw53699e91996-12-10 23:23:01 +00001227static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001228posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001229{
Mark Hammondef8b6542001-05-13 08:04:26 +00001230 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001231}
1232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001233
Guido van Rossumb6775db1994-08-01 11:34:53 +00001234#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001235static char posix_uname__doc__[] =
1236"uname() -> (sysname, nodename, release, version, machine)\n\
1237Return a tuple identifying the current operating system.";
1238
Barry Warsaw53699e91996-12-10 23:23:01 +00001239static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001240posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001241{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001242 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001243 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001244 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001245 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001246 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001247 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001248 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001249 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001250 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001251 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001252 u.sysname,
1253 u.nodename,
1254 u.release,
1255 u.version,
1256 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001257}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001258#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001259
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001260
1261static char posix_utime__doc__[] =
1262"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001263utime(path, None) -> None\n\
1264Set the access and modified time of the file to the given values. If the\n\
1265second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001266
Barry Warsaw53699e91996-12-10 23:23:01 +00001267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001268posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001270 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001271 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001272 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001273 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001274
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001275/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001276#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001277 struct utimbuf buf;
1278#define ATIME buf.actime
1279#define MTIME buf.modtime
1280#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001281#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001282 time_t buf[2];
1283#define ATIME buf[0]
1284#define MTIME buf[1]
1285#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001286#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001287
Barry Warsaw3cef8562000-05-01 16:17:24 +00001288 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001289 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001290 if (arg == Py_None) {
1291 /* optional time values not given */
1292 Py_BEGIN_ALLOW_THREADS
1293 res = utime(path, NULL);
1294 Py_END_ALLOW_THREADS
1295 }
1296 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1297 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001298 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001299 return NULL;
1300 }
1301 else {
1302 ATIME = atime;
1303 MTIME = mtime;
1304 Py_BEGIN_ALLOW_THREADS
1305 res = utime(path, UTIME_ARG);
1306 Py_END_ALLOW_THREADS
1307 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001308 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001309 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001310 Py_INCREF(Py_None);
1311 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001312#undef UTIME_ARG
1313#undef ATIME
1314#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001315}
1316
Guido van Rossum85e3b011991-06-03 12:42:10 +00001317
Guido van Rossum3b066191991-06-04 19:40:25 +00001318/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001319
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001320static char posix__exit__doc__[] =
1321"_exit(status)\n\
1322Exit to the system with specified status, without normal exit processing.";
1323
Barry Warsaw53699e91996-12-10 23:23:01 +00001324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001325posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001326{
1327 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001328 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001329 return NULL;
1330 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001331 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001332}
1333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001334
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001335#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001336static char posix_execv__doc__[] =
1337"execv(path, args)\n\
1338Execute an executable path with arguments, replacing current process.\n\
1339\n\
1340 path: path of executable file\n\
1341 args: tuple or list of strings";
1342
Barry Warsaw53699e91996-12-10 23:23:01 +00001343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001344posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001345{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001346 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001347 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001348 char **argvlist;
1349 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001350 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001351
Guido van Rossum89b33251993-10-22 14:26:06 +00001352 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001353 argv is a list or tuple of strings. */
1354
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001355 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001356 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001357 if (PyList_Check(argv)) {
1358 argc = PyList_Size(argv);
1359 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001360 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001361 else if (PyTuple_Check(argv)) {
1362 argc = PyTuple_Size(argv);
1363 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001364 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001365 else {
Fred Drake661ea262000-10-24 19:57:45 +00001366 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001367 return NULL;
1368 }
1369
1370 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001371 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001372 return NULL;
1373 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001374
Barry Warsaw53699e91996-12-10 23:23:01 +00001375 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001376 if (argvlist == NULL)
1377 return NULL;
1378 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001379 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1380 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001381 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001382 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001383 return NULL;
1384
Guido van Rossum85e3b011991-06-03 12:42:10 +00001385 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001386 }
1387 argvlist[argc] = NULL;
1388
Guido van Rossumb6775db1994-08-01 11:34:53 +00001389#ifdef BAD_EXEC_PROTOTYPES
1390 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001391#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001392 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001393#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001394
Guido van Rossum85e3b011991-06-03 12:42:10 +00001395 /* If we get here it's definitely an error */
1396
Barry Warsaw53699e91996-12-10 23:23:01 +00001397 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001398 return posix_error();
1399}
1400
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001401
1402static char posix_execve__doc__[] =
1403"execve(path, args, env)\n\
1404Execute a path with arguments and environment, replacing current process.\n\
1405\n\
1406 path: path of executable file\n\
1407 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001408 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001409
Barry Warsaw53699e91996-12-10 23:23:01 +00001410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001411posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001412{
1413 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001414 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001415 char **argvlist;
1416 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001417 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001418 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001419 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001420
1421 /* execve has three arguments: (path, argv, env), where
1422 argv is a list or tuple of strings and env is a dictionary
1423 like posix.environ. */
1424
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001425 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001426 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001427 if (PyList_Check(argv)) {
1428 argc = PyList_Size(argv);
1429 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001430 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001431 else if (PyTuple_Check(argv)) {
1432 argc = PyTuple_Size(argv);
1433 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001434 }
1435 else {
Fred Drake661ea262000-10-24 19:57:45 +00001436 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001437 return NULL;
1438 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001439 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001440 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001441 return NULL;
1442 }
1443
Guido van Rossum50422b42000-04-26 20:34:28 +00001444 if (argc == 0) {
1445 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001446 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001447 return NULL;
1448 }
1449
Barry Warsaw53699e91996-12-10 23:23:01 +00001450 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001451 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001452 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001453 return NULL;
1454 }
1455 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001456 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001457 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001458 &argvlist[i]))
1459 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001460 goto fail_1;
1461 }
1462 }
1463 argvlist[argc] = NULL;
1464
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001465 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001466 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001467 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001468 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001469 goto fail_1;
1470 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001471 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001472 keys = PyMapping_Keys(env);
1473 vals = PyMapping_Values(env);
1474 if (!keys || !vals)
1475 goto fail_2;
1476
1477 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001478 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001479
1480 key = PyList_GetItem(keys, pos);
1481 val = PyList_GetItem(vals, pos);
1482 if (!key || !val)
1483 goto fail_2;
1484
Fred Drake661ea262000-10-24 19:57:45 +00001485 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1486 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001487 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001488 goto fail_2;
1489 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001490
1491#if defined(PYOS_OS2)
1492 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1493 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1494#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001495 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001496 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001497 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001498 goto fail_2;
1499 }
1500 sprintf(p, "%s=%s", k, v);
1501 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001502#if defined(PYOS_OS2)
1503 }
1504#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001505 }
1506 envlist[envc] = 0;
1507
Guido van Rossumb6775db1994-08-01 11:34:53 +00001508
1509#ifdef BAD_EXEC_PROTOTYPES
1510 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001511#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001512 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001513#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001514
1515 /* If we get here it's definitely an error */
1516
1517 (void) posix_error();
1518
1519 fail_2:
1520 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001521 PyMem_DEL(envlist[envc]);
1522 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001523 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001524 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001525 Py_XDECREF(vals);
1526 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001527 return NULL;
1528}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001529#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001530
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001531
Guido van Rossuma1065681999-01-25 23:20:23 +00001532#ifdef HAVE_SPAWNV
1533static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001534"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001535Execute an executable path with arguments, replacing current process.\n\
1536\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001537 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001538 path: path of executable file\n\
1539 args: tuple or list of strings";
1540
1541static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001542posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001543{
1544 char *path;
1545 PyObject *argv;
1546 char **argvlist;
1547 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001548 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001549 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001550
1551 /* spawnv has three arguments: (mode, path, argv), where
1552 argv is a list or tuple of strings. */
1553
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001554 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001555 return NULL;
1556 if (PyList_Check(argv)) {
1557 argc = PyList_Size(argv);
1558 getitem = PyList_GetItem;
1559 }
1560 else if (PyTuple_Check(argv)) {
1561 argc = PyTuple_Size(argv);
1562 getitem = PyTuple_GetItem;
1563 }
1564 else {
Fred Drake661ea262000-10-24 19:57:45 +00001565 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001566 return NULL;
1567 }
1568
1569 argvlist = PyMem_NEW(char *, argc+1);
1570 if (argvlist == NULL)
1571 return NULL;
1572 for (i = 0; i < argc; i++) {
1573 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1574 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001575 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001576 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001577 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001578 }
1579 }
1580 argvlist[argc] = NULL;
1581
Guido van Rossum246bc171999-02-01 23:54:31 +00001582 if (mode == _OLD_P_OVERLAY)
1583 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001584 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001585
1586 PyMem_DEL(argvlist);
1587
Fred Drake699f3522000-06-29 21:12:41 +00001588 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001589 return posix_error();
1590 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001591#if SIZEOF_LONG == SIZEOF_VOID_P
1592 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001593#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001594 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001595#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001596}
1597
1598
1599static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001600"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001601Execute a path with arguments and environment, replacing current process.\n\
1602\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001603 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001604 path: path of executable file\n\
1605 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001606 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001607
1608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001609posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001610{
1611 char *path;
1612 PyObject *argv, *env;
1613 char **argvlist;
1614 char **envlist;
1615 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1616 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001617 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001618 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001619
1620 /* spawnve has four arguments: (mode, path, argv, env), where
1621 argv is a list or tuple of strings and env is a dictionary
1622 like posix.environ. */
1623
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001624 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001625 return NULL;
1626 if (PyList_Check(argv)) {
1627 argc = PyList_Size(argv);
1628 getitem = PyList_GetItem;
1629 }
1630 else if (PyTuple_Check(argv)) {
1631 argc = PyTuple_Size(argv);
1632 getitem = PyTuple_GetItem;
1633 }
1634 else {
Fred Drake661ea262000-10-24 19:57:45 +00001635 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001636 return NULL;
1637 }
1638 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001639 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001640 return NULL;
1641 }
1642
1643 argvlist = PyMem_NEW(char *, argc+1);
1644 if (argvlist == NULL) {
1645 PyErr_NoMemory();
1646 return NULL;
1647 }
1648 for (i = 0; i < argc; i++) {
1649 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001650 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001651 &argvlist[i]))
1652 {
1653 goto fail_1;
1654 }
1655 }
1656 argvlist[argc] = NULL;
1657
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001658 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001659 envlist = PyMem_NEW(char *, i + 1);
1660 if (envlist == NULL) {
1661 PyErr_NoMemory();
1662 goto fail_1;
1663 }
1664 envc = 0;
1665 keys = PyMapping_Keys(env);
1666 vals = PyMapping_Values(env);
1667 if (!keys || !vals)
1668 goto fail_2;
1669
1670 for (pos = 0; pos < i; pos++) {
1671 char *p, *k, *v;
1672
1673 key = PyList_GetItem(keys, pos);
1674 val = PyList_GetItem(vals, pos);
1675 if (!key || !val)
1676 goto fail_2;
1677
Fred Drake661ea262000-10-24 19:57:45 +00001678 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1679 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001680 {
1681 goto fail_2;
1682 }
1683 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1684 if (p == NULL) {
1685 PyErr_NoMemory();
1686 goto fail_2;
1687 }
1688 sprintf(p, "%s=%s", k, v);
1689 envlist[envc++] = p;
1690 }
1691 envlist[envc] = 0;
1692
Guido van Rossum246bc171999-02-01 23:54:31 +00001693 if (mode == _OLD_P_OVERLAY)
1694 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001695 spawnval = _spawnve(mode, path, argvlist, envlist);
1696 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001697 (void) posix_error();
1698 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001699#if SIZEOF_LONG == SIZEOF_VOID_P
1700 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001701#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001702 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001703#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001704
1705 fail_2:
1706 while (--envc >= 0)
1707 PyMem_DEL(envlist[envc]);
1708 PyMem_DEL(envlist);
1709 fail_1:
1710 PyMem_DEL(argvlist);
1711 Py_XDECREF(vals);
1712 Py_XDECREF(keys);
1713 return res;
1714}
1715#endif /* HAVE_SPAWNV */
1716
1717
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001718#ifdef HAVE_FORK1
1719static char posix_fork1__doc__[] =
1720"fork1() -> pid\n\
1721Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1722\n\
1723Return 0 to child process and PID of child to parent process.";
1724
1725static PyObject *
1726posix_fork1(self, args)
1727 PyObject *self;
1728 PyObject *args;
1729{
1730 int pid;
1731 if (!PyArg_ParseTuple(args, ":fork1"))
1732 return NULL;
1733 pid = fork1();
1734 if (pid == -1)
1735 return posix_error();
1736 PyOS_AfterFork();
1737 return PyInt_FromLong((long)pid);
1738}
1739#endif
1740
1741
Guido van Rossumad0ee831995-03-01 10:34:45 +00001742#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001743static char posix_fork__doc__[] =
1744"fork() -> pid\n\
1745Fork a child process.\n\
1746\n\
1747Return 0 to child process and PID of child to parent process.";
1748
Barry Warsaw53699e91996-12-10 23:23:01 +00001749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001750posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001751{
1752 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001753 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001754 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001755 pid = fork();
1756 if (pid == -1)
1757 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001758 if (pid == 0)
1759 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001760 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001761}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001762#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001763
Fred Drake8cef4cf2000-06-28 16:40:38 +00001764#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1765#ifdef HAVE_PTY_H
1766#include <pty.h>
1767#else
1768#ifdef HAVE_LIBUTIL_H
1769#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001770#endif /* HAVE_LIBUTIL_H */
1771#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001772#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001773
Thomas Wouters70c21a12000-07-14 14:28:33 +00001774#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001775static char posix_openpty__doc__[] =
1776"openpty() -> (master_fd, slave_fd)\n\
1777Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1778
1779static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001780posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001781{
1782 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001783#ifndef HAVE_OPENPTY
1784 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001785#endif
1786
Fred Drake8cef4cf2000-06-28 16:40:38 +00001787 if (!PyArg_ParseTuple(args, ":openpty"))
1788 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001789
1790#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001791 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1792 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001793#else
1794 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1795 if (slave_name == NULL)
1796 return posix_error();
1797
1798 slave_fd = open(slave_name, O_RDWR);
1799 if (slave_fd < 0)
1800 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001801#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001802
Fred Drake8cef4cf2000-06-28 16:40:38 +00001803 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001804
Fred Drake8cef4cf2000-06-28 16:40:38 +00001805}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001806#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001807
1808#ifdef HAVE_FORKPTY
1809static char posix_forkpty__doc__[] =
1810"forkpty() -> (pid, master_fd)\n\
1811Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1812Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1813To both, return fd of newly opened pseudo-terminal.\n";
1814
1815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001816posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001817{
1818 int master_fd, pid;
1819
1820 if (!PyArg_ParseTuple(args, ":forkpty"))
1821 return NULL;
1822 pid = forkpty(&master_fd, NULL, NULL, NULL);
1823 if (pid == -1)
1824 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001825 if (pid == 0)
1826 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001827 return Py_BuildValue("(ii)", pid, master_fd);
1828}
1829#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001830
Guido van Rossumad0ee831995-03-01 10:34:45 +00001831#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001832static char posix_getegid__doc__[] =
1833"getegid() -> egid\n\
1834Return the current process's effective group id.";
1835
Barry Warsaw53699e91996-12-10 23:23:01 +00001836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001837posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001838{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001839 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001840 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001841 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001842}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001843#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001844
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001845
Guido van Rossumad0ee831995-03-01 10:34:45 +00001846#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001847static char posix_geteuid__doc__[] =
1848"geteuid() -> euid\n\
1849Return the current process's effective user id.";
1850
Barry Warsaw53699e91996-12-10 23:23:01 +00001851static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001852posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001853{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001854 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001855 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001856 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001857}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001858#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001859
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001860
Guido van Rossumad0ee831995-03-01 10:34:45 +00001861#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001862static char posix_getgid__doc__[] =
1863"getgid() -> gid\n\
1864Return the current process's group id.";
1865
Barry Warsaw53699e91996-12-10 23:23:01 +00001866static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001867posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001868{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001869 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001870 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001871 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001872}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001873#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001874
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001875
1876static char posix_getpid__doc__[] =
1877"getpid() -> pid\n\
1878Return the current process id";
1879
Barry Warsaw53699e91996-12-10 23:23:01 +00001880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001881posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001882{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001883 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001884 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001885 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001886}
1887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001888
Fred Drakec9680921999-12-13 16:37:25 +00001889#ifdef HAVE_GETGROUPS
1890static char posix_getgroups__doc__[] = "\
1891getgroups() -> list of group IDs\n\
1892Return list of supplemental group IDs for the process.";
1893
1894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001895posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001896{
1897 PyObject *result = NULL;
1898
1899 if (PyArg_ParseTuple(args, ":getgroups")) {
1900#ifdef NGROUPS_MAX
1901#define MAX_GROUPS NGROUPS_MAX
1902#else
1903 /* defined to be 16 on Solaris7, so this should be a small number */
1904#define MAX_GROUPS 64
1905#endif
1906 gid_t grouplist[MAX_GROUPS];
1907 int n;
1908
1909 n = getgroups(MAX_GROUPS, grouplist);
1910 if (n < 0)
1911 posix_error();
1912 else {
1913 result = PyList_New(n);
1914 if (result != NULL) {
1915 PyObject *o;
1916 int i;
1917 for (i = 0; i < n; ++i) {
1918 o = PyInt_FromLong((long)grouplist[i]);
1919 if (o == NULL) {
1920 Py_DECREF(result);
1921 result = NULL;
1922 break;
1923 }
1924 PyList_SET_ITEM(result, i, o);
1925 }
1926 }
1927 }
1928 }
1929 return result;
1930}
1931#endif
1932
Guido van Rossumb6775db1994-08-01 11:34:53 +00001933#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001934static char posix_getpgrp__doc__[] =
1935"getpgrp() -> pgrp\n\
1936Return the current process group id.";
1937
Barry Warsaw53699e91996-12-10 23:23:01 +00001938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001939posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001940{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001941 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001942 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001943#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001944 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001945#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001946 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001947#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001948}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001949#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001950
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001951
Guido van Rossumb6775db1994-08-01 11:34:53 +00001952#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001953static char posix_setpgrp__doc__[] =
1954"setpgrp() -> None\n\
1955Make this process a session leader.";
1956
Barry Warsaw53699e91996-12-10 23:23:01 +00001957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001958posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001959{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001960 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001961 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001962#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001963 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001964#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001965 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001966#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001967 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001968 Py_INCREF(Py_None);
1969 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001970}
1971
Guido van Rossumb6775db1994-08-01 11:34:53 +00001972#endif /* HAVE_SETPGRP */
1973
Guido van Rossumad0ee831995-03-01 10:34:45 +00001974#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001975static char posix_getppid__doc__[] =
1976"getppid() -> ppid\n\
1977Return the parent's process id.";
1978
Barry Warsaw53699e91996-12-10 23:23:01 +00001979static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001980posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001981{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001982 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001983 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001984 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001985}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001986#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001988
Fred Drake12c6e2d1999-12-14 21:25:03 +00001989#ifdef HAVE_GETLOGIN
1990static char posix_getlogin__doc__[] = "\
1991getlogin() -> string\n\
1992Return the actual login name.";
1993
1994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001995posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001996{
1997 PyObject *result = NULL;
1998
1999 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002000 char *name;
2001 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002002
Fred Drakea30680b2000-12-06 21:24:28 +00002003 errno = 0;
2004 name = getlogin();
2005 if (name == NULL) {
2006 if (errno)
2007 posix_error();
2008 else
2009 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002010 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002011 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002012 else
2013 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002014 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002015 }
2016 return result;
2017}
2018#endif
2019
Guido van Rossumad0ee831995-03-01 10:34:45 +00002020#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002021static char posix_getuid__doc__[] =
2022"getuid() -> uid\n\
2023Return the current process's user id.";
2024
Barry Warsaw53699e91996-12-10 23:23:01 +00002025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002026posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002027{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002028 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002029 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002030 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002031}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002032#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002034
Guido van Rossumad0ee831995-03-01 10:34:45 +00002035#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002036static char posix_kill__doc__[] =
2037"kill(pid, sig) -> None\n\
2038Kill a process with a signal.";
2039
Barry Warsaw53699e91996-12-10 23:23:01 +00002040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002041posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002042{
2043 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002044 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002045 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002046#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002047 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2048 APIRET rc;
2049 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002050 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002051
2052 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2053 APIRET rc;
2054 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002055 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002056
2057 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002058 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002059#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002060 if (kill(pid, sig) == -1)
2061 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002062#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002063 Py_INCREF(Py_None);
2064 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002065}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002066#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002067
Guido van Rossumc0125471996-06-28 18:55:32 +00002068#ifdef HAVE_PLOCK
2069
2070#ifdef HAVE_SYS_LOCK_H
2071#include <sys/lock.h>
2072#endif
2073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002074static char posix_plock__doc__[] =
2075"plock(op) -> None\n\
2076Lock program segments into memory.";
2077
Barry Warsaw53699e91996-12-10 23:23:01 +00002078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002079posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002080{
2081 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002082 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002083 return NULL;
2084 if (plock(op) == -1)
2085 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 Py_INCREF(Py_None);
2087 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002088}
2089#endif
2090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002091
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002092#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002093static char posix_popen__doc__[] =
2094"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2095Open a pipe to/from a command returning a file object.";
2096
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002097#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002098static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002099async_system(const char *command)
2100{
2101 char *p, errormsg[256], args[1024];
2102 RESULTCODES rcodes;
2103 APIRET rc;
2104 char *shell = getenv("COMSPEC");
2105 if (!shell)
2106 shell = "cmd";
2107
2108 strcpy(args, shell);
2109 p = &args[ strlen(args)+1 ];
2110 strcpy(p, "/c ");
2111 strcat(p, command);
2112 p += strlen(p) + 1;
2113 *p = '\0';
2114
2115 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002116 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002117 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002118 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002119 &rcodes, shell);
2120 return rc;
2121}
2122
Guido van Rossumd48f2521997-12-05 22:19:34 +00002123static FILE *
2124popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002125{
2126 HFILE rhan, whan;
2127 FILE *retfd = NULL;
2128 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2129
Guido van Rossumd48f2521997-12-05 22:19:34 +00002130 if (rc != NO_ERROR) {
2131 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002132 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002133 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002134
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002135 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2136 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002137
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002138 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2139 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002140
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002141 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2142 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002143
2144 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002145 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002146 }
2147
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002148 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2149 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002150
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002151 close(oldfd); /* And Close Saved STDOUT Handle */
2152 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002153
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002154 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2155 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002156
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002157 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2158 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002159
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002160 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2161 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002162
2163 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002164 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002165 }
2166
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002167 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2168 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002169
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002170 close(oldfd); /* And Close Saved STDIN Handle */
2171 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002172
Guido van Rossumd48f2521997-12-05 22:19:34 +00002173 } else {
2174 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002175 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002176 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002177}
2178
2179static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002180posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002181{
2182 char *name;
2183 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002184 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002185 FILE *fp;
2186 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002187 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002188 return NULL;
2189 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002190 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002191 Py_END_ALLOW_THREADS
2192 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002193 return os2_error(err);
2194
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002195 f = PyFile_FromFile(fp, name, mode, fclose);
2196 if (f != NULL)
2197 PyFile_SetBufSize(f, bufsize);
2198 return f;
2199}
2200
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002201#elif defined(MS_WIN32)
2202
2203/*
2204 * Portable 'popen' replacement for Win32.
2205 *
2206 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2207 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002208 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002209 */
2210
2211#include <malloc.h>
2212#include <io.h>
2213#include <fcntl.h>
2214
2215/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2216#define POPEN_1 1
2217#define POPEN_2 2
2218#define POPEN_3 3
2219#define POPEN_4 4
2220
2221static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002222static int _PyPclose(FILE *file);
2223
2224/*
2225 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002226 * for use when retrieving the process exit code. See _PyPclose() below
2227 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002228 */
2229static PyObject *_PyPopenProcs = NULL;
2230
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002231
2232/* popen that works from a GUI.
2233 *
2234 * The result of this function is a pipe (file) connected to the
2235 * processes stdin or stdout, depending on the requested mode.
2236 */
2237
2238static PyObject *
2239posix_popen(PyObject *self, PyObject *args)
2240{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002241 PyObject *f, *s;
2242 int tm = 0;
2243
2244 char *cmdstring;
2245 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002246 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002247 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002248 return NULL;
2249
2250 s = PyTuple_New(0);
2251
2252 if (*mode == 'r')
2253 tm = _O_RDONLY;
2254 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002255 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002256 return NULL;
2257 } else
2258 tm = _O_WRONLY;
2259
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002260 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002261 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002262 return NULL;
2263 }
2264
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002265 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002266 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002267 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002268 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002269 else
2270 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2271
2272 return f;
2273}
2274
2275/* Variation on win32pipe.popen
2276 *
2277 * The result of this function is a pipe (file) connected to the
2278 * process's stdin, and a pipe connected to the process's stdout.
2279 */
2280
2281static PyObject *
2282win32_popen2(PyObject *self, PyObject *args)
2283{
2284 PyObject *f;
2285 int tm=0;
2286
2287 char *cmdstring;
2288 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002289 int bufsize = -1;
2290 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002291 return NULL;
2292
2293 if (*mode == 't')
2294 tm = _O_TEXT;
2295 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002296 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002297 return NULL;
2298 } else
2299 tm = _O_BINARY;
2300
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002301 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002302 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002303 return NULL;
2304 }
2305
2306 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002307
2308 return f;
2309}
2310
2311/*
2312 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002313 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002314 * The result of this function is 3 pipes - the process's stdin,
2315 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002316 */
2317
2318static PyObject *
2319win32_popen3(PyObject *self, PyObject *args)
2320{
2321 PyObject *f;
2322 int tm = 0;
2323
2324 char *cmdstring;
2325 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002326 int bufsize = -1;
2327 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002328 return NULL;
2329
2330 if (*mode == 't')
2331 tm = _O_TEXT;
2332 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002333 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002334 return NULL;
2335 } else
2336 tm = _O_BINARY;
2337
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002338 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002339 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002340 return NULL;
2341 }
2342
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002343 f = _PyPopen(cmdstring, tm, POPEN_3);
2344
2345 return f;
2346}
2347
2348/*
2349 * Variation on win32pipe.popen
2350 *
2351 * The result of this function is 2 pipes - the processes stdin,
2352 * and stdout+stderr combined as a single pipe.
2353 */
2354
2355static PyObject *
2356win32_popen4(PyObject *self, PyObject *args)
2357{
2358 PyObject *f;
2359 int tm = 0;
2360
2361 char *cmdstring;
2362 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002363 int bufsize = -1;
2364 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002365 return NULL;
2366
2367 if (*mode == 't')
2368 tm = _O_TEXT;
2369 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002370 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002371 return NULL;
2372 } else
2373 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002374
2375 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002376 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002377 return NULL;
2378 }
2379
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002380 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002381
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002382 return f;
2383}
2384
Mark Hammond08501372001-01-31 07:30:29 +00002385static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002386_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002387 HANDLE hStdin,
2388 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002389 HANDLE hStderr,
2390 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002391{
2392 PROCESS_INFORMATION piProcInfo;
2393 STARTUPINFO siStartInfo;
2394 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002395 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002396 int i;
2397 int x;
2398
2399 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2400 s1 = (char *)_alloca(i);
2401 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2402 return x;
2403 if (GetVersion() < 0x80000000) {
2404 /*
2405 * NT/2000
2406 */
2407 x = i + strlen(s3) + strlen(cmdstring) + 1;
2408 s2 = (char *)_alloca(x);
2409 ZeroMemory(s2, x);
2410 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2411 }
2412 else {
2413 /*
2414 * Oh gag, we're on Win9x. Use the workaround listed in
2415 * KB: Q150956
2416 */
Mark Hammond08501372001-01-31 07:30:29 +00002417 char modulepath[_MAX_PATH];
2418 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002419 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2420 for (i = x = 0; modulepath[i]; i++)
2421 if (modulepath[i] == '\\')
2422 x = i+1;
2423 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002424 /* Create the full-name to w9xpopen, so we can test it exists */
2425 strncat(modulepath,
2426 szConsoleSpawn,
2427 (sizeof(modulepath)/sizeof(modulepath[0]))
2428 -strlen(modulepath));
2429 if (stat(modulepath, &statinfo) != 0) {
2430 /* Eeek - file-not-found - possibly an embedding
2431 situation - see if we can locate it in sys.prefix
2432 */
2433 strncpy(modulepath,
2434 Py_GetExecPrefix(),
2435 sizeof(modulepath)/sizeof(modulepath[0]));
2436 if (modulepath[strlen(modulepath)-1] != '\\')
2437 strcat(modulepath, "\\");
2438 strncat(modulepath,
2439 szConsoleSpawn,
2440 (sizeof(modulepath)/sizeof(modulepath[0]))
2441 -strlen(modulepath));
2442 /* No where else to look - raise an easily identifiable
2443 error, rather than leaving Windows to report
2444 "file not found" - as the user is probably blissfully
2445 unaware this shim EXE is used, and it will confuse them.
2446 (well, it confused me for a while ;-)
2447 */
2448 if (stat(modulepath, &statinfo) != 0) {
2449 PyErr_Format(PyExc_RuntimeError,
2450 "Can not locate '%s' which is needed "
2451 "for popen to work on this platform.",
2452 szConsoleSpawn);
2453 return FALSE;
2454 }
2455 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002456 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2457 strlen(modulepath) +
2458 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002459
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002460 s2 = (char *)_alloca(x);
2461 ZeroMemory(s2, x);
2462 sprintf(
2463 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002464 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002465 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002466 s1,
2467 s3,
2468 cmdstring);
2469 }
2470 }
2471
2472 /* Could be an else here to try cmd.exe / command.com in the path
2473 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002474 else {
2475 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2476 return FALSE;
2477 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002478
2479 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2480 siStartInfo.cb = sizeof(STARTUPINFO);
2481 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2482 siStartInfo.hStdInput = hStdin;
2483 siStartInfo.hStdOutput = hStdout;
2484 siStartInfo.hStdError = hStderr;
2485 siStartInfo.wShowWindow = SW_HIDE;
2486
2487 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002488 s2,
2489 NULL,
2490 NULL,
2491 TRUE,
2492 CREATE_NEW_CONSOLE,
2493 NULL,
2494 NULL,
2495 &siStartInfo,
2496 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002497 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002498 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002499
Mark Hammondb37a3732000-08-14 04:47:33 +00002500 /* Return process handle */
2501 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002502 return TRUE;
2503 }
Mark Hammond08501372001-01-31 07:30:29 +00002504 win32_error("CreateProcess", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002505 return FALSE;
2506}
2507
2508/* The following code is based off of KB: Q190351 */
2509
2510static PyObject *
2511_PyPopen(char *cmdstring, int mode, int n)
2512{
2513 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2514 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002515 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002516
2517 SECURITY_ATTRIBUTES saAttr;
2518 BOOL fSuccess;
2519 int fd1, fd2, fd3;
2520 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002521 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002522 PyObject *f;
2523
2524 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2525 saAttr.bInheritHandle = TRUE;
2526 saAttr.lpSecurityDescriptor = NULL;
2527
2528 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2529 return win32_error("CreatePipe", NULL);
2530
2531 /* Create new output read handle and the input write handle. Set
2532 * the inheritance properties to FALSE. Otherwise, the child inherits
2533 * the these handles; resulting in non-closeable handles to the pipes
2534 * being created. */
2535 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002536 GetCurrentProcess(), &hChildStdinWrDup, 0,
2537 FALSE,
2538 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002539 if (!fSuccess)
2540 return win32_error("DuplicateHandle", NULL);
2541
2542 /* Close the inheritable version of ChildStdin
2543 that we're using. */
2544 CloseHandle(hChildStdinWr);
2545
2546 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2547 return win32_error("CreatePipe", NULL);
2548
2549 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002550 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2551 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002552 if (!fSuccess)
2553 return win32_error("DuplicateHandle", NULL);
2554
2555 /* Close the inheritable version of ChildStdout
2556 that we're using. */
2557 CloseHandle(hChildStdoutRd);
2558
2559 if (n != POPEN_4) {
2560 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2561 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002562 fSuccess = DuplicateHandle(GetCurrentProcess(),
2563 hChildStderrRd,
2564 GetCurrentProcess(),
2565 &hChildStderrRdDup, 0,
2566 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002567 if (!fSuccess)
2568 return win32_error("DuplicateHandle", NULL);
2569 /* Close the inheritable version of ChildStdErr that we're using. */
2570 CloseHandle(hChildStderrRd);
2571 }
2572
2573 switch (n) {
2574 case POPEN_1:
2575 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2576 case _O_WRONLY | _O_TEXT:
2577 /* Case for writing to child Stdin in text mode. */
2578 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2579 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002580 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002581 PyFile_SetBufSize(f, 0);
2582 /* We don't care about these pipes anymore, so close them. */
2583 CloseHandle(hChildStdoutRdDup);
2584 CloseHandle(hChildStderrRdDup);
2585 break;
2586
2587 case _O_RDONLY | _O_TEXT:
2588 /* Case for reading from child Stdout in text mode. */
2589 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2590 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002591 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002592 PyFile_SetBufSize(f, 0);
2593 /* We don't care about these pipes anymore, so close them. */
2594 CloseHandle(hChildStdinWrDup);
2595 CloseHandle(hChildStderrRdDup);
2596 break;
2597
2598 case _O_RDONLY | _O_BINARY:
2599 /* Case for readinig from child Stdout in binary mode. */
2600 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2601 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002602 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002603 PyFile_SetBufSize(f, 0);
2604 /* We don't care about these pipes anymore, so close them. */
2605 CloseHandle(hChildStdinWrDup);
2606 CloseHandle(hChildStderrRdDup);
2607 break;
2608
2609 case _O_WRONLY | _O_BINARY:
2610 /* Case for writing to child Stdin in binary mode. */
2611 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2612 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002613 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002614 PyFile_SetBufSize(f, 0);
2615 /* We don't care about these pipes anymore, so close them. */
2616 CloseHandle(hChildStdoutRdDup);
2617 CloseHandle(hChildStderrRdDup);
2618 break;
2619 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002620 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002621 break;
2622
2623 case POPEN_2:
2624 case POPEN_4:
2625 {
2626 char *m1, *m2;
2627 PyObject *p1, *p2;
2628
2629 if (mode && _O_TEXT) {
2630 m1 = "r";
2631 m2 = "w";
2632 } else {
2633 m1 = "rb";
2634 m2 = "wb";
2635 }
2636
2637 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2638 f1 = _fdopen(fd1, m2);
2639 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2640 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002641 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002642 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002643 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002644 PyFile_SetBufSize(p2, 0);
2645
2646 if (n != 4)
2647 CloseHandle(hChildStderrRdDup);
2648
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002649 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002650 Py_XDECREF(p1);
2651 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002652 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002653 break;
2654 }
2655
2656 case POPEN_3:
2657 {
2658 char *m1, *m2;
2659 PyObject *p1, *p2, *p3;
2660
2661 if (mode && _O_TEXT) {
2662 m1 = "r";
2663 m2 = "w";
2664 } else {
2665 m1 = "rb";
2666 m2 = "wb";
2667 }
2668
2669 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2670 f1 = _fdopen(fd1, m2);
2671 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2672 f2 = _fdopen(fd2, m1);
2673 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2674 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002675 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002676 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2677 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002678 PyFile_SetBufSize(p1, 0);
2679 PyFile_SetBufSize(p2, 0);
2680 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002681 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002682 Py_XDECREF(p1);
2683 Py_XDECREF(p2);
2684 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002685 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002686 break;
2687 }
2688 }
2689
2690 if (n == POPEN_4) {
2691 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002692 hChildStdinRd,
2693 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002694 hChildStdoutWr,
2695 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002696 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002697 }
2698 else {
2699 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002700 hChildStdinRd,
2701 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002702 hChildStderrWr,
2703 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002704 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002705 }
2706
Mark Hammondb37a3732000-08-14 04:47:33 +00002707 /*
2708 * Insert the files we've created into the process dictionary
2709 * all referencing the list with the process handle and the
2710 * initial number of files (see description below in _PyPclose).
2711 * Since if _PyPclose later tried to wait on a process when all
2712 * handles weren't closed, it could create a deadlock with the
2713 * child, we spend some energy here to try to ensure that we
2714 * either insert all file handles into the dictionary or none
2715 * at all. It's a little clumsy with the various popen modes
2716 * and variable number of files involved.
2717 */
2718 if (!_PyPopenProcs) {
2719 _PyPopenProcs = PyDict_New();
2720 }
2721
2722 if (_PyPopenProcs) {
2723 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2724 int ins_rc[3];
2725
2726 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2727 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2728
2729 procObj = PyList_New(2);
2730 hProcessObj = PyLong_FromVoidPtr(hProcess);
2731 intObj = PyInt_FromLong(file_count);
2732
2733 if (procObj && hProcessObj && intObj) {
2734 PyList_SetItem(procObj,0,hProcessObj);
2735 PyList_SetItem(procObj,1,intObj);
2736
2737 fileObj[0] = PyLong_FromVoidPtr(f1);
2738 if (fileObj[0]) {
2739 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2740 fileObj[0],
2741 procObj);
2742 }
2743 if (file_count >= 2) {
2744 fileObj[1] = PyLong_FromVoidPtr(f2);
2745 if (fileObj[1]) {
2746 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2747 fileObj[1],
2748 procObj);
2749 }
2750 }
2751 if (file_count >= 3) {
2752 fileObj[2] = PyLong_FromVoidPtr(f3);
2753 if (fileObj[2]) {
2754 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2755 fileObj[2],
2756 procObj);
2757 }
2758 }
2759
2760 if (ins_rc[0] < 0 || !fileObj[0] ||
2761 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2762 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2763 /* Something failed - remove any dictionary
2764 * entries that did make it.
2765 */
2766 if (!ins_rc[0] && fileObj[0]) {
2767 PyDict_DelItem(_PyPopenProcs,
2768 fileObj[0]);
2769 }
2770 if (!ins_rc[1] && fileObj[1]) {
2771 PyDict_DelItem(_PyPopenProcs,
2772 fileObj[1]);
2773 }
2774 if (!ins_rc[2] && fileObj[2]) {
2775 PyDict_DelItem(_PyPopenProcs,
2776 fileObj[2]);
2777 }
2778 }
2779 }
2780
2781 /*
2782 * Clean up our localized references for the dictionary keys
2783 * and value since PyDict_SetItem will Py_INCREF any copies
2784 * that got placed in the dictionary.
2785 */
2786 Py_XDECREF(procObj);
2787 Py_XDECREF(fileObj[0]);
2788 Py_XDECREF(fileObj[1]);
2789 Py_XDECREF(fileObj[2]);
2790 }
2791
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002792 /* Child is launched. Close the parents copy of those pipe
2793 * handles that only the child should have open. You need to
2794 * make sure that no handles to the write end of the output pipe
2795 * are maintained in this process or else the pipe will not close
2796 * when the child process exits and the ReadFile will hang. */
2797
2798 if (!CloseHandle(hChildStdinRd))
2799 return win32_error("CloseHandle", NULL);
2800
2801 if (!CloseHandle(hChildStdoutWr))
2802 return win32_error("CloseHandle", NULL);
2803
2804 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2805 return win32_error("CloseHandle", NULL);
2806
2807 return f;
2808}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002809
2810/*
2811 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2812 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002813 *
2814 * This function uses the _PyPopenProcs dictionary in order to map the
2815 * input file pointer to information about the process that was
2816 * originally created by the popen* call that created the file pointer.
2817 * The dictionary uses the file pointer as a key (with one entry
2818 * inserted for each file returned by the original popen* call) and a
2819 * single list object as the value for all files from a single call.
2820 * The list object contains the Win32 process handle at [0], and a file
2821 * count at [1], which is initialized to the total number of file
2822 * handles using that list.
2823 *
2824 * This function closes whichever handle it is passed, and decrements
2825 * the file count in the dictionary for the process handle pointed to
2826 * by this file. On the last close (when the file count reaches zero),
2827 * this function will wait for the child process and then return its
2828 * exit code as the result of the close() operation. This permits the
2829 * files to be closed in any order - it is always the close() of the
2830 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002831 */
Tim Peters736aa322000-09-01 06:51:24 +00002832
2833 /* RED_FLAG 31-Aug-2000 Tim
2834 * This is always called (today!) between a pair of
2835 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2836 * macros. So the thread running this has no valid thread state, as
2837 * far as Python is concerned. However, this calls some Python API
2838 * functions that cannot be called safely without a valid thread
2839 * state, in particular PyDict_GetItem.
2840 * As a temporary hack (although it may last for years ...), we
2841 * *rely* on not having a valid thread state in this function, in
2842 * order to create our own "from scratch".
2843 * This will deadlock if _PyPclose is ever called by a thread
2844 * holding the global lock.
2845 */
2846
Fredrik Lundh56055a42000-07-23 19:47:12 +00002847static int _PyPclose(FILE *file)
2848{
Fredrik Lundh20318932000-07-26 17:29:12 +00002849 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002850 DWORD exit_code;
2851 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002852 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2853 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002854#ifdef WITH_THREAD
2855 PyInterpreterState* pInterpreterState;
2856 PyThreadState* pThreadState;
2857#endif
2858
Fredrik Lundh20318932000-07-26 17:29:12 +00002859 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002860 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002861 */
2862 result = fclose(file);
2863
Tim Peters736aa322000-09-01 06:51:24 +00002864#ifdef WITH_THREAD
2865 /* Bootstrap a valid thread state into existence. */
2866 pInterpreterState = PyInterpreterState_New();
2867 if (!pInterpreterState) {
2868 /* Well, we're hosed now! We don't have a thread
2869 * state, so can't call a nice error routine, or raise
2870 * an exception. Just die.
2871 */
2872 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002873 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002874 return -1; /* unreachable */
2875 }
2876 pThreadState = PyThreadState_New(pInterpreterState);
2877 if (!pThreadState) {
2878 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002879 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002880 return -1; /* unreachable */
2881 }
2882 /* Grab the global lock. Note that this will deadlock if the
2883 * current thread already has the lock! (see RED_FLAG comments
2884 * before this function)
2885 */
2886 PyEval_RestoreThread(pThreadState);
2887#endif
2888
Fredrik Lundh56055a42000-07-23 19:47:12 +00002889 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002890 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2891 (procObj = PyDict_GetItem(_PyPopenProcs,
2892 fileObj)) != NULL &&
2893 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2894 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2895
2896 hProcess = PyLong_AsVoidPtr(hProcessObj);
2897 file_count = PyInt_AsLong(intObj);
2898
2899 if (file_count > 1) {
2900 /* Still other files referencing process */
2901 file_count--;
2902 PyList_SetItem(procObj,1,
2903 PyInt_FromLong(file_count));
2904 } else {
2905 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002906 if (result != EOF &&
2907 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2908 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002909 /* Possible truncation here in 16-bit environments, but
2910 * real exit codes are just the lower byte in any event.
2911 */
2912 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002913 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002914 /* Indicate failure - this will cause the file object
2915 * to raise an I/O error and translate the last Win32
2916 * error code from errno. We do have a problem with
2917 * last errors that overlap the normal errno table,
2918 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002919 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002920 if (result != EOF) {
2921 /* If the error wasn't from the fclose(), then
2922 * set errno for the file object error handling.
2923 */
2924 errno = GetLastError();
2925 }
2926 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002927 }
2928
2929 /* Free up the native handle at this point */
2930 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002931 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002932
Mark Hammondb37a3732000-08-14 04:47:33 +00002933 /* Remove this file pointer from dictionary */
2934 PyDict_DelItem(_PyPopenProcs, fileObj);
2935
2936 if (PyDict_Size(_PyPopenProcs) == 0) {
2937 Py_DECREF(_PyPopenProcs);
2938 _PyPopenProcs = NULL;
2939 }
2940
2941 } /* if object retrieval ok */
2942
2943 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002944 } /* if _PyPopenProcs */
2945
Tim Peters736aa322000-09-01 06:51:24 +00002946#ifdef WITH_THREAD
2947 /* Tear down the thread & interpreter states.
2948 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002949 * call the thread clear & delete functions, and indeed insist on
2950 * doing that themselves. The lock must be held during the clear, but
2951 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002952 */
2953 PyInterpreterState_Clear(pInterpreterState);
2954 PyEval_ReleaseThread(pThreadState);
2955 PyInterpreterState_Delete(pInterpreterState);
2956#endif
2957
Fredrik Lundh56055a42000-07-23 19:47:12 +00002958 return result;
2959}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002960
2961#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002963posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002964{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002965 char *name;
2966 char *mode = "r";
2967 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002968 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002969 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002970 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002971 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002972 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002973 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002974 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002975 if (fp == NULL)
2976 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002977 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002978 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002979 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002980 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002981}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002982#endif
2983
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002984#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002986
Guido van Rossumb6775db1994-08-01 11:34:53 +00002987#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002988static char posix_setuid__doc__[] =
2989"setuid(uid) -> None\n\
2990Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002991static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002992posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002993{
2994 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002995 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002996 return NULL;
2997 if (setuid(uid) < 0)
2998 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002999 Py_INCREF(Py_None);
3000 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003001}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003002#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003003
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003004
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003005#ifdef HAVE_SETEUID
3006static char posix_seteuid__doc__[] =
3007"seteuid(uid) -> None\n\
3008Set the current process's effective user id.";
3009static PyObject *
3010posix_seteuid (PyObject *self, PyObject *args)
3011{
3012 int euid;
3013 if (!PyArg_ParseTuple(args, "i", &euid)) {
3014 return NULL;
3015 } else if (seteuid(euid) < 0) {
3016 return posix_error();
3017 } else {
3018 Py_INCREF(Py_None);
3019 return Py_None;
3020 }
3021}
3022#endif /* HAVE_SETEUID */
3023
3024#ifdef HAVE_SETEGID
3025static char posix_setegid__doc__[] =
3026"setegid(gid) -> None\n\
3027Set the current process's effective group id.";
3028static PyObject *
3029posix_setegid (PyObject *self, PyObject *args)
3030{
3031 int egid;
3032 if (!PyArg_ParseTuple(args, "i", &egid)) {
3033 return NULL;
3034 } else if (setegid(egid) < 0) {
3035 return posix_error();
3036 } else {
3037 Py_INCREF(Py_None);
3038 return Py_None;
3039 }
3040}
3041#endif /* HAVE_SETEGID */
3042
3043#ifdef HAVE_SETREUID
3044static char posix_setreuid__doc__[] =
3045"seteuid(ruid, euid) -> None\n\
3046Set the current process's real and effective user ids.";
3047static PyObject *
3048posix_setreuid (PyObject *self, PyObject *args)
3049{
3050 int ruid, euid;
3051 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3052 return NULL;
3053 } else if (setreuid(ruid, euid) < 0) {
3054 return posix_error();
3055 } else {
3056 Py_INCREF(Py_None);
3057 return Py_None;
3058 }
3059}
3060#endif /* HAVE_SETREUID */
3061
3062#ifdef HAVE_SETREGID
3063static char posix_setregid__doc__[] =
3064"setegid(rgid, egid) -> None\n\
3065Set the current process's real and effective group ids.";
3066static PyObject *
3067posix_setregid (PyObject *self, PyObject *args)
3068{
3069 int rgid, egid;
3070 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3071 return NULL;
3072 } else if (setregid(rgid, egid) < 0) {
3073 return posix_error();
3074 } else {
3075 Py_INCREF(Py_None);
3076 return Py_None;
3077 }
3078}
3079#endif /* HAVE_SETREGID */
3080
Guido van Rossumb6775db1994-08-01 11:34:53 +00003081#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082static char posix_setgid__doc__[] =
3083"setgid(gid) -> None\n\
3084Set the current process's group id.";
3085
Barry Warsaw53699e91996-12-10 23:23:01 +00003086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003087posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003088{
3089 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003090 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003091 return NULL;
3092 if (setgid(gid) < 0)
3093 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003094 Py_INCREF(Py_None);
3095 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003096}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003097#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003099
Guido van Rossumb6775db1994-08-01 11:34:53 +00003100#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003101static char posix_waitpid__doc__[] =
3102"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003103Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003104
Barry Warsaw53699e91996-12-10 23:23:01 +00003105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003106posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003107{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003108 int pid, options;
3109#ifdef UNION_WAIT
3110 union wait status;
3111#define status_i (status.w_status)
3112#else
3113 int status;
3114#define status_i status
3115#endif
3116 status_i = 0;
3117
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003118 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003119 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003120 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003121#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003122 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003123#else
3124 pid = waitpid(pid, &status, options);
3125#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003126 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003127 if (pid == -1)
3128 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003129 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003130 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003131}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003132#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003133
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003134
Guido van Rossumad0ee831995-03-01 10:34:45 +00003135#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003136static char posix_wait__doc__[] =
3137"wait() -> (pid, status)\n\
3138Wait for completion of a child process.";
3139
Barry Warsaw53699e91996-12-10 23:23:01 +00003140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003141posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003142{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003143 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003144#ifdef UNION_WAIT
3145 union wait status;
3146#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003147#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003148 int status;
3149#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003150#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003151 if (!PyArg_ParseTuple(args, ":wait"))
3152 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003153 status_i = 0;
3154 Py_BEGIN_ALLOW_THREADS
3155 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003156 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003157 if (pid == -1)
3158 return posix_error();
3159 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003160 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003161#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003162}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003163#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003165
3166static char posix_lstat__doc__[] =
3167"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3168Like stat(path), but do not follow symbolic links.";
3169
Barry Warsaw53699e91996-12-10 23:23:01 +00003170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003171posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003172{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003173#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003174 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003175#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003176 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003177#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003178}
3179
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003180
Guido van Rossumb6775db1994-08-01 11:34:53 +00003181#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003182static char posix_readlink__doc__[] =
3183"readlink(path) -> path\n\
3184Return a string representing the path to which the symbolic link points.";
3185
Barry Warsaw53699e91996-12-10 23:23:01 +00003186static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003187posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003188{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003189 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003190 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003191 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003192 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003193 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003194 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003195 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003196 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003197 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003198 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003199 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003200}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003201#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003203
Guido van Rossumb6775db1994-08-01 11:34:53 +00003204#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003205static char posix_symlink__doc__[] =
3206"symlink(src, dst) -> None\n\
3207Create a symbolic link.";
3208
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003210posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003211{
Mark Hammondef8b6542001-05-13 08:04:26 +00003212 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003213}
3214#endif /* HAVE_SYMLINK */
3215
3216
3217#ifdef HAVE_TIMES
3218#ifndef HZ
3219#define HZ 60 /* Universal constant :-) */
3220#endif /* HZ */
3221
Guido van Rossumd48f2521997-12-05 22:19:34 +00003222#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3223static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003224system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003225{
3226 ULONG value = 0;
3227
3228 Py_BEGIN_ALLOW_THREADS
3229 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3230 Py_END_ALLOW_THREADS
3231
3232 return value;
3233}
3234
3235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003236posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003237{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003238 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003239 return NULL;
3240
3241 /* Currently Only Uptime is Provided -- Others Later */
3242 return Py_BuildValue("ddddd",
3243 (double)0 /* t.tms_utime / HZ */,
3244 (double)0 /* t.tms_stime / HZ */,
3245 (double)0 /* t.tms_cutime / HZ */,
3246 (double)0 /* t.tms_cstime / HZ */,
3247 (double)system_uptime() / 1000);
3248}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003249#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003251posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003252{
3253 struct tms t;
3254 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003255 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003256 return NULL;
3257 errno = 0;
3258 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003259 if (c == (clock_t) -1)
3260 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003261 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003262 (double)t.tms_utime / HZ,
3263 (double)t.tms_stime / HZ,
3264 (double)t.tms_cutime / HZ,
3265 (double)t.tms_cstime / HZ,
3266 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003267}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003268#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003269#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003270
3271
Guido van Rossum87755a21996-09-07 00:59:43 +00003272#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003273#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003275posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003276{
3277 FILETIME create, exit, kernel, user;
3278 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003279 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003280 return NULL;
3281 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003282 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3283 /* The fields of a FILETIME structure are the hi and lo part
3284 of a 64-bit value expressed in 100 nanosecond units.
3285 1e7 is one second in such units; 1e-7 the inverse.
3286 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3287 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003288 return Py_BuildValue(
3289 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003290 (double)(kernel.dwHighDateTime*429.4967296 +
3291 kernel.dwLowDateTime*1e-7),
3292 (double)(user.dwHighDateTime*429.4967296 +
3293 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003294 (double)0,
3295 (double)0,
3296 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003297}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003298#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003299
3300#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003301static char posix_times__doc__[] =
3302"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3303Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003304#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003305
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003306
Guido van Rossumb6775db1994-08-01 11:34:53 +00003307#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003308static char posix_setsid__doc__[] =
3309"setsid() -> None\n\
3310Call the system call setsid().";
3311
Barry Warsaw53699e91996-12-10 23:23:01 +00003312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003313posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003314{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003315 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003316 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003317 if (setsid() < 0)
3318 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003319 Py_INCREF(Py_None);
3320 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003321}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003322#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003323
Guido van Rossumb6775db1994-08-01 11:34:53 +00003324#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003325static char posix_setpgid__doc__[] =
3326"setpgid(pid, pgrp) -> None\n\
3327Call the system call setpgid().";
3328
Barry Warsaw53699e91996-12-10 23:23:01 +00003329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003330posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003331{
3332 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003333 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003334 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003335 if (setpgid(pid, pgrp) < 0)
3336 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003337 Py_INCREF(Py_None);
3338 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003339}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003340#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003342
Guido van Rossumb6775db1994-08-01 11:34:53 +00003343#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003344static char posix_tcgetpgrp__doc__[] =
3345"tcgetpgrp(fd) -> pgid\n\
3346Return the process group associated with the terminal given by a fd.";
3347
Barry Warsaw53699e91996-12-10 23:23:01 +00003348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003349posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003350{
3351 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003352 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003353 return NULL;
3354 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003355 if (pgid < 0)
3356 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003357 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003358}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003359#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003360
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003361
Guido van Rossumb6775db1994-08-01 11:34:53 +00003362#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003363static char posix_tcsetpgrp__doc__[] =
3364"tcsetpgrp(fd, pgid) -> None\n\
3365Set the process group associated with the terminal given by a fd.";
3366
Barry Warsaw53699e91996-12-10 23:23:01 +00003367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003368posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003369{
3370 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003371 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003372 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003373 if (tcsetpgrp(fd, pgid) < 0)
3374 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003375 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003376 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003377}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003378#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003379
Guido van Rossum687dd131993-05-17 08:34:16 +00003380/* Functions acting on file descriptors */
3381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003382static char posix_open__doc__[] =
3383"open(filename, flag [, mode=0777]) -> fd\n\
3384Open a file (for low level IO).";
3385
Barry Warsaw53699e91996-12-10 23:23:01 +00003386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003387posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003388{
Mark Hammondef8b6542001-05-13 08:04:26 +00003389 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003390 int flag;
3391 int mode = 0777;
3392 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003393 if (!PyArg_ParseTuple(args, "eti|i",
3394 Py_FileSystemDefaultEncoding, &file,
3395 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003396 return NULL;
3397
Barry Warsaw53699e91996-12-10 23:23:01 +00003398 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003399 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003400 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003401 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003402 return posix_error_with_allocated_filename(file);
3403 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003404 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003405}
3406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003407
3408static char posix_close__doc__[] =
3409"close(fd) -> None\n\
3410Close a file descriptor (for low level IO).";
3411
Barry Warsaw53699e91996-12-10 23:23:01 +00003412static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003413posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003414{
3415 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003416 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003417 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003418 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003419 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003420 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003421 if (res < 0)
3422 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003423 Py_INCREF(Py_None);
3424 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003425}
3426
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003427
3428static char posix_dup__doc__[] =
3429"dup(fd) -> fd2\n\
3430Return a duplicate of a file descriptor.";
3431
Barry Warsaw53699e91996-12-10 23:23:01 +00003432static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003433posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003434{
3435 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003436 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003437 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003438 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003439 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003440 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003441 if (fd < 0)
3442 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003443 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003444}
3445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003446
3447static char posix_dup2__doc__[] =
3448"dup2(fd, fd2) -> None\n\
3449Duplicate file descriptor.";
3450
Barry Warsaw53699e91996-12-10 23:23:01 +00003451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003452posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003453{
3454 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003455 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003456 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003457 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003458 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003459 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003460 if (res < 0)
3461 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003462 Py_INCREF(Py_None);
3463 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003464}
3465
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003466
3467static char posix_lseek__doc__[] =
3468"lseek(fd, pos, how) -> newpos\n\
3469Set the current position of a file descriptor.";
3470
Barry Warsaw53699e91996-12-10 23:23:01 +00003471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003472posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003473{
3474 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003475#ifdef MS_WIN64
3476 LONG_LONG pos, res;
3477#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003478 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003479#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003480 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003481 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003482 return NULL;
3483#ifdef SEEK_SET
3484 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3485 switch (how) {
3486 case 0: how = SEEK_SET; break;
3487 case 1: how = SEEK_CUR; break;
3488 case 2: how = SEEK_END; break;
3489 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003490#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003491
3492#if !defined(HAVE_LARGEFILE_SUPPORT)
3493 pos = PyInt_AsLong(posobj);
3494#else
3495 pos = PyLong_Check(posobj) ?
3496 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3497#endif
3498 if (PyErr_Occurred())
3499 return NULL;
3500
Barry Warsaw53699e91996-12-10 23:23:01 +00003501 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003502#ifdef MS_WIN64
3503 res = _lseeki64(fd, pos, how);
3504#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003505 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003506#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003507 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003508 if (res < 0)
3509 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003510
3511#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003512 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003513#else
3514 return PyLong_FromLongLong(res);
3515#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003516}
3517
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003518
3519static char posix_read__doc__[] =
3520"read(fd, buffersize) -> string\n\
3521Read a file descriptor.";
3522
Barry Warsaw53699e91996-12-10 23:23:01 +00003523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003524posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003525{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003526 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003527 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003528 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003529 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003530 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003531 if (buffer == NULL)
3532 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003533 Py_BEGIN_ALLOW_THREADS
3534 n = read(fd, PyString_AsString(buffer), size);
3535 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003536 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003537 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003538 return posix_error();
3539 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003540 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003541 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003542 return buffer;
3543}
3544
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003545
3546static char posix_write__doc__[] =
3547"write(fd, string) -> byteswritten\n\
3548Write a string to a file descriptor.";
3549
Barry Warsaw53699e91996-12-10 23:23:01 +00003550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003551posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003552{
3553 int fd, size;
3554 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003555 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003556 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003557 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003558 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003559 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003560 if (size < 0)
3561 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003562 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003563}
3564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003565
3566static char posix_fstat__doc__[]=
3567"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3568Like stat(), but for an open file descriptor.";
3569
Barry Warsaw53699e91996-12-10 23:23:01 +00003570static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003571posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003572{
3573 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003574 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003575 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003576 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003577 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003578 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003579 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003580 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003581 if (res != 0)
3582 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003583
3584 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003585}
3586
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003587
3588static char posix_fdopen__doc__[] =
3589"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3590Return an open file object connected to a file descriptor.";
3591
Barry Warsaw53699e91996-12-10 23:23:01 +00003592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003593posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003594{
Guido van Rossum687dd131993-05-17 08:34:16 +00003595 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003596 char *mode = "r";
3597 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003598 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003599 PyObject *f;
3600 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003601 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003602
Barry Warsaw53699e91996-12-10 23:23:01 +00003603 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003604 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003605 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003606 if (fp == NULL)
3607 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003608 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003609 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003610 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003611 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003612}
3613
Skip Montanaro1517d842000-07-19 14:34:14 +00003614static char posix_isatty__doc__[] =
3615"isatty(fd) -> Boolean\n\
3616Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003617connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003618
3619static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003620posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003621{
3622 int fd;
3623 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3624 return NULL;
3625 return Py_BuildValue("i", isatty(fd));
3626}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003627
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003628#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003629static char posix_pipe__doc__[] =
3630"pipe() -> (read_end, write_end)\n\
3631Create a pipe.";
3632
Barry Warsaw53699e91996-12-10 23:23:01 +00003633static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003634posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003635{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003636#if defined(PYOS_OS2)
3637 HFILE read, write;
3638 APIRET rc;
3639
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003640 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003641 return NULL;
3642
3643 Py_BEGIN_ALLOW_THREADS
3644 rc = DosCreatePipe( &read, &write, 4096);
3645 Py_END_ALLOW_THREADS
3646 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003647 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003648
3649 return Py_BuildValue("(ii)", read, write);
3650#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003651#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003652 int fds[2];
3653 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003654 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003655 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003656 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003657 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003658 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003659 if (res != 0)
3660 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003661 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003662#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003663 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003664 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003665 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003666 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003667 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003668 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003669 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003670 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003671 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003672 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003673 read_fd = _open_osfhandle((intptr_t)read, 0);
3674 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003675 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003676#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003677#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003678}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003679#endif /* HAVE_PIPE */
3680
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003681
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003682#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003683static char posix_mkfifo__doc__[] =
3684"mkfifo(file, [, mode=0666]) -> None\n\
3685Create a FIFO (a POSIX named pipe).";
3686
Barry Warsaw53699e91996-12-10 23:23:01 +00003687static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003688posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003689{
3690 char *file;
3691 int mode = 0666;
3692 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003693 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003694 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003695 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003696 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003697 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003698 if (res < 0)
3699 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003700 Py_INCREF(Py_None);
3701 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003702}
3703#endif
3704
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003705
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003706#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003707static char posix_ftruncate__doc__[] =
3708"ftruncate(fd, length) -> None\n\
3709Truncate a file to a specified length.";
3710
Barry Warsaw53699e91996-12-10 23:23:01 +00003711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003712posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003713{
3714 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003715 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003716 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003717 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003718
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003719 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003720 return NULL;
3721
3722#if !defined(HAVE_LARGEFILE_SUPPORT)
3723 length = PyInt_AsLong(lenobj);
3724#else
3725 length = PyLong_Check(lenobj) ?
3726 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3727#endif
3728 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003729 return NULL;
3730
Barry Warsaw53699e91996-12-10 23:23:01 +00003731 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003732 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003733 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003734 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003735 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003736 return NULL;
3737 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003738 Py_INCREF(Py_None);
3739 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003740}
3741#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003742
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003743#ifdef NeXT
3744#define HAVE_PUTENV
3745/* Steve Spicklemire got this putenv from NeXTAnswers */
3746static int
3747putenv(char *newval)
3748{
3749 extern char **environ;
3750
3751 static int firstTime = 1;
3752 char **ep;
3753 char *cp;
3754 int esiz;
3755 char *np;
3756
3757 if (!(np = strchr(newval, '=')))
3758 return 1;
3759 *np = '\0';
3760
3761 /* look it up */
3762 for (ep=environ ; *ep ; ep++)
3763 {
3764 /* this should always be true... */
3765 if (cp = strchr(*ep, '='))
3766 {
3767 *cp = '\0';
3768 if (!strcmp(*ep, newval))
3769 {
3770 /* got it! */
3771 *cp = '=';
3772 break;
3773 }
3774 *cp = '=';
3775 }
3776 else
3777 {
3778 *np = '=';
3779 return 1;
3780 }
3781 }
3782
3783 *np = '=';
3784 if (*ep)
3785 {
3786 /* the string was already there:
3787 just replace it with the new one */
3788 *ep = newval;
3789 return 0;
3790 }
3791
3792 /* expand environ by one */
3793 for (esiz=2, ep=environ ; *ep ; ep++)
3794 esiz++;
3795 if (firstTime)
3796 {
3797 char **epp;
3798 char **newenv;
3799 if (!(newenv = malloc(esiz * sizeof(char *))))
3800 return 1;
3801
3802 for (ep=environ, epp=newenv ; *ep ;)
3803 *epp++ = *ep++;
3804 *epp++ = newval;
3805 *epp = (char *) 0;
3806 environ = newenv;
3807 }
3808 else
3809 {
3810 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3811 return 1;
3812 environ[esiz - 2] = newval;
3813 environ[esiz - 1] = (char *) 0;
3814 firstTime = 0;
3815 }
3816
3817 return 0;
3818}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003819#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003820
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003821
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003822#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003823static char posix_putenv__doc__[] =
3824"putenv(key, value) -> None\n\
3825Change or add an environment variable.";
3826
Fred Drake762e2061999-08-26 17:23:54 +00003827/* Save putenv() parameters as values here, so we can collect them when they
3828 * get re-set with another call for the same key. */
3829static PyObject *posix_putenv_garbage;
3830
Barry Warsaw53699e91996-12-10 23:23:01 +00003831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003832posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003833{
3834 char *s1, *s2;
3835 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003836 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003837
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003838 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003839 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003840
3841#if defined(PYOS_OS2)
3842 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3843 APIRET rc;
3844
3845 if (strlen(s2) == 0) /* If New Value is an Empty String */
3846 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3847
3848 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3849 if (rc != NO_ERROR)
3850 return os2_error(rc);
3851
3852 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3853 APIRET rc;
3854
3855 if (strlen(s2) == 0) /* If New Value is an Empty String */
3856 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3857
3858 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3859 if (rc != NO_ERROR)
3860 return os2_error(rc);
3861 } else {
3862#endif
3863
Fred Drake762e2061999-08-26 17:23:54 +00003864 /* XXX This can leak memory -- not easy to fix :-( */
3865 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3866 if (newstr == NULL)
3867 return PyErr_NoMemory();
3868 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003869 (void) sprintf(new, "%s=%s", s1, s2);
3870 if (putenv(new)) {
3871 posix_error();
3872 return NULL;
3873 }
Fred Drake762e2061999-08-26 17:23:54 +00003874 /* Install the first arg and newstr in posix_putenv_garbage;
3875 * this will cause previous value to be collected. This has to
3876 * happen after the real putenv() call because the old value
3877 * was still accessible until then. */
3878 if (PyDict_SetItem(posix_putenv_garbage,
3879 PyTuple_GET_ITEM(args, 0), newstr)) {
3880 /* really not much we can do; just leak */
3881 PyErr_Clear();
3882 }
3883 else {
3884 Py_DECREF(newstr);
3885 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003886
3887#if defined(PYOS_OS2)
3888 }
3889#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003890 Py_INCREF(Py_None);
3891 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003892}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003893#endif /* putenv */
3894
3895#ifdef HAVE_STRERROR
3896static char posix_strerror__doc__[] =
3897"strerror(code) -> string\n\
3898Translate an error code to a message string.";
3899
Guido van Rossumf68d8e52001-04-14 17:55:09 +00003900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003901posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003902{
3903 int code;
3904 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003905 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003906 return NULL;
3907 message = strerror(code);
3908 if (message == NULL) {
3909 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003910 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003911 return NULL;
3912 }
3913 return PyString_FromString(message);
3914}
3915#endif /* strerror */
3916
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003917
Guido van Rossumc9641791998-08-04 15:26:23 +00003918#ifdef HAVE_SYS_WAIT_H
3919
3920#ifdef WIFSTOPPED
3921static char posix_WIFSTOPPED__doc__[] =
3922"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003923Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003924
3925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003926posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003927{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003928#ifdef UNION_WAIT
3929 union wait status;
3930#define status_i (status.w_status)
3931#else
3932 int status;
3933#define status_i status
3934#endif
3935 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003936
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003937 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003938 {
3939 return NULL;
3940 }
3941
3942 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003943#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003944}
3945#endif /* WIFSTOPPED */
3946
3947#ifdef WIFSIGNALED
3948static char posix_WIFSIGNALED__doc__[] =
3949"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003950Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003951
3952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003953posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003954{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003955#ifdef UNION_WAIT
3956 union wait status;
3957#define status_i (status.w_status)
3958#else
3959 int status;
3960#define status_i status
3961#endif
3962 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003963
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003964 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003965 {
3966 return NULL;
3967 }
3968
3969 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003970#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003971}
3972#endif /* WIFSIGNALED */
3973
3974#ifdef WIFEXITED
3975static char posix_WIFEXITED__doc__[] =
3976"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003977Return true if the process returning 'status' exited using the exit()\n\
3978system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003979
3980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003981posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003982{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003983#ifdef UNION_WAIT
3984 union wait status;
3985#define status_i (status.w_status)
3986#else
3987 int status;
3988#define status_i status
3989#endif
3990 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003991
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003992 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003993 {
3994 return NULL;
3995 }
3996
3997 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003998#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003999}
4000#endif /* WIFEXITED */
4001
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004002#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004003static char posix_WEXITSTATUS__doc__[] =
4004"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004005Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004006
4007static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004008posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004009{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004010#ifdef UNION_WAIT
4011 union wait status;
4012#define status_i (status.w_status)
4013#else
4014 int status;
4015#define status_i status
4016#endif
4017 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004018
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004019 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004020 {
4021 return NULL;
4022 }
4023
4024 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004025#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004026}
4027#endif /* WEXITSTATUS */
4028
4029#ifdef WTERMSIG
4030static char posix_WTERMSIG__doc__[] =
4031"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004032Return the signal that terminated the process that provided the 'status'\n\
4033value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004034
4035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004036posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004037{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004038#ifdef UNION_WAIT
4039 union wait status;
4040#define status_i (status.w_status)
4041#else
4042 int status;
4043#define status_i status
4044#endif
4045 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004046
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004047 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004048 {
4049 return NULL;
4050 }
4051
4052 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004053#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004054}
4055#endif /* WTERMSIG */
4056
4057#ifdef WSTOPSIG
4058static char posix_WSTOPSIG__doc__[] =
4059"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004060Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004061
4062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004063posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004064{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004065#ifdef UNION_WAIT
4066 union wait status;
4067#define status_i (status.w_status)
4068#else
4069 int status;
4070#define status_i status
4071#endif
4072 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004073
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004074 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004075 {
4076 return NULL;
4077 }
4078
4079 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004080#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004081}
4082#endif /* WSTOPSIG */
4083
4084#endif /* HAVE_SYS_WAIT_H */
4085
4086
Guido van Rossum94f6f721999-01-06 18:42:14 +00004087#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004088#ifdef _SCO_DS
4089/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4090 needed definitions in sys/statvfs.h */
4091#define _SVID3
4092#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004093#include <sys/statvfs.h>
4094
4095static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004096"fstatvfs(fd) -> \n\
4097 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004098Perform an fstatvfs system call on the given fd.";
4099
4100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004101posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004102{
4103 int fd, res;
4104 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004105 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004106 return NULL;
4107 Py_BEGIN_ALLOW_THREADS
4108 res = fstatvfs(fd, &st);
4109 Py_END_ALLOW_THREADS
4110 if (res != 0)
4111 return posix_error();
4112#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004113 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004114 (long) st.f_bsize,
4115 (long) st.f_frsize,
4116 (long) st.f_blocks,
4117 (long) st.f_bfree,
4118 (long) st.f_bavail,
4119 (long) st.f_files,
4120 (long) st.f_ffree,
4121 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004122 (long) st.f_flag,
4123 (long) st.f_namemax);
4124#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004125 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004126 (long) st.f_bsize,
4127 (long) st.f_frsize,
4128 (LONG_LONG) st.f_blocks,
4129 (LONG_LONG) st.f_bfree,
4130 (LONG_LONG) st.f_bavail,
4131 (LONG_LONG) st.f_files,
4132 (LONG_LONG) st.f_ffree,
4133 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004134 (long) st.f_flag,
4135 (long) st.f_namemax);
4136#endif
4137}
4138#endif /* HAVE_FSTATVFS */
4139
4140
4141#if defined(HAVE_STATVFS)
4142#include <sys/statvfs.h>
4143
4144static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004145"statvfs(path) -> \n\
4146 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004147Perform a statvfs system call on the given path.";
4148
4149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004150posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004151{
4152 char *path;
4153 int res;
4154 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004155 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004156 return NULL;
4157 Py_BEGIN_ALLOW_THREADS
4158 res = statvfs(path, &st);
4159 Py_END_ALLOW_THREADS
4160 if (res != 0)
4161 return posix_error_with_filename(path);
4162#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004163 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004164 (long) st.f_bsize,
4165 (long) st.f_frsize,
4166 (long) st.f_blocks,
4167 (long) st.f_bfree,
4168 (long) st.f_bavail,
4169 (long) st.f_files,
4170 (long) st.f_ffree,
4171 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004172 (long) st.f_flag,
4173 (long) st.f_namemax);
4174#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004175 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004176 (long) st.f_bsize,
4177 (long) st.f_frsize,
4178 (LONG_LONG) st.f_blocks,
4179 (LONG_LONG) st.f_bfree,
4180 (LONG_LONG) st.f_bavail,
4181 (LONG_LONG) st.f_files,
4182 (LONG_LONG) st.f_ffree,
4183 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004184 (long) st.f_flag,
4185 (long) st.f_namemax);
4186#endif
4187}
4188#endif /* HAVE_STATVFS */
4189
4190
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004191#ifdef HAVE_TEMPNAM
4192static char posix_tempnam__doc__[] = "\
4193tempnam([dir[, prefix]]) -> string\n\
4194Return a unique name for a temporary file.\n\
4195The directory and a short may be specified as strings; they may be omitted\n\
4196or None if not needed.";
4197
4198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004199posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004200{
4201 PyObject *result = NULL;
4202 char *dir = NULL;
4203 char *pfx = NULL;
4204 char *name;
4205
4206 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4207 return NULL;
4208 name = tempnam(dir, pfx);
4209 if (name == NULL)
4210 return PyErr_NoMemory();
4211 result = PyString_FromString(name);
4212 free(name);
4213 return result;
4214}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004215#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004216
4217
4218#ifdef HAVE_TMPFILE
4219static char posix_tmpfile__doc__[] = "\
4220tmpfile() -> file object\n\
4221Create a temporary file with no directory entries.";
4222
4223static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004224posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004225{
4226 FILE *fp;
4227
4228 if (!PyArg_ParseTuple(args, ":tmpfile"))
4229 return NULL;
4230 fp = tmpfile();
4231 if (fp == NULL)
4232 return posix_error();
4233 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4234}
4235#endif
4236
4237
4238#ifdef HAVE_TMPNAM
4239static char posix_tmpnam__doc__[] = "\
4240tmpnam() -> string\n\
4241Return a unique name for a temporary file.";
4242
4243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004244posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004245{
4246 char buffer[L_tmpnam];
4247 char *name;
4248
4249 if (!PyArg_ParseTuple(args, ":tmpnam"))
4250 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004251#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004252 name = tmpnam_r(buffer);
4253#else
4254 name = tmpnam(buffer);
4255#endif
4256 if (name == NULL) {
4257 PyErr_SetObject(PyExc_OSError,
4258 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004259#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004260 "unexpected NULL from tmpnam_r"
4261#else
4262 "unexpected NULL from tmpnam"
4263#endif
4264 ));
4265 return NULL;
4266 }
4267 return PyString_FromString(buffer);
4268}
4269#endif
4270
4271
Fred Drakec9680921999-12-13 16:37:25 +00004272/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4273 * It maps strings representing configuration variable names to
4274 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004275 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004276 * rarely-used constants. There are three separate tables that use
4277 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004278 *
4279 * This code is always included, even if none of the interfaces that
4280 * need it are included. The #if hackery needed to avoid it would be
4281 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004282 */
4283struct constdef {
4284 char *name;
4285 long value;
4286};
4287
Fred Drake12c6e2d1999-12-14 21:25:03 +00004288static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004289conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4290 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004291{
4292 if (PyInt_Check(arg)) {
4293 *valuep = PyInt_AS_LONG(arg);
4294 return 1;
4295 }
4296 if (PyString_Check(arg)) {
4297 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004298 size_t lo = 0;
4299 size_t mid;
4300 size_t hi = tablesize;
4301 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004302 char *confname = PyString_AS_STRING(arg);
4303 while (lo < hi) {
4304 mid = (lo + hi) / 2;
4305 cmp = strcmp(confname, table[mid].name);
4306 if (cmp < 0)
4307 hi = mid;
4308 else if (cmp > 0)
4309 lo = mid + 1;
4310 else {
4311 *valuep = table[mid].value;
4312 return 1;
4313 }
4314 }
4315 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4316 }
4317 else
4318 PyErr_SetString(PyExc_TypeError,
4319 "configuration names must be strings or integers");
4320 return 0;
4321}
4322
4323
4324#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4325static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004326#ifdef _PC_ABI_AIO_XFER_MAX
4327 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4328#endif
4329#ifdef _PC_ABI_ASYNC_IO
4330 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4331#endif
Fred Drakec9680921999-12-13 16:37:25 +00004332#ifdef _PC_ASYNC_IO
4333 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4334#endif
4335#ifdef _PC_CHOWN_RESTRICTED
4336 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4337#endif
4338#ifdef _PC_FILESIZEBITS
4339 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4340#endif
4341#ifdef _PC_LAST
4342 {"PC_LAST", _PC_LAST},
4343#endif
4344#ifdef _PC_LINK_MAX
4345 {"PC_LINK_MAX", _PC_LINK_MAX},
4346#endif
4347#ifdef _PC_MAX_CANON
4348 {"PC_MAX_CANON", _PC_MAX_CANON},
4349#endif
4350#ifdef _PC_MAX_INPUT
4351 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4352#endif
4353#ifdef _PC_NAME_MAX
4354 {"PC_NAME_MAX", _PC_NAME_MAX},
4355#endif
4356#ifdef _PC_NO_TRUNC
4357 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4358#endif
4359#ifdef _PC_PATH_MAX
4360 {"PC_PATH_MAX", _PC_PATH_MAX},
4361#endif
4362#ifdef _PC_PIPE_BUF
4363 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4364#endif
4365#ifdef _PC_PRIO_IO
4366 {"PC_PRIO_IO", _PC_PRIO_IO},
4367#endif
4368#ifdef _PC_SOCK_MAXBUF
4369 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4370#endif
4371#ifdef _PC_SYNC_IO
4372 {"PC_SYNC_IO", _PC_SYNC_IO},
4373#endif
4374#ifdef _PC_VDISABLE
4375 {"PC_VDISABLE", _PC_VDISABLE},
4376#endif
4377};
4378
Fred Drakec9680921999-12-13 16:37:25 +00004379static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004380conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004381{
4382 return conv_confname(arg, valuep, posix_constants_pathconf,
4383 sizeof(posix_constants_pathconf)
4384 / sizeof(struct constdef));
4385}
4386#endif
4387
4388#ifdef HAVE_FPATHCONF
4389static char posix_fpathconf__doc__[] = "\
4390fpathconf(fd, name) -> integer\n\
4391Return the configuration limit name for the file descriptor fd.\n\
4392If there is no limit, return -1.";
4393
4394static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004395posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004396{
4397 PyObject *result = NULL;
4398 int name, fd;
4399
Fred Drake12c6e2d1999-12-14 21:25:03 +00004400 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4401 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004402 long limit;
4403
4404 errno = 0;
4405 limit = fpathconf(fd, name);
4406 if (limit == -1 && errno != 0)
4407 posix_error();
4408 else
4409 result = PyInt_FromLong(limit);
4410 }
4411 return result;
4412}
4413#endif
4414
4415
4416#ifdef HAVE_PATHCONF
4417static char posix_pathconf__doc__[] = "\
4418pathconf(path, name) -> integer\n\
4419Return the configuration limit name for the file or directory path.\n\
4420If there is no limit, return -1.";
4421
4422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004423posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004424{
4425 PyObject *result = NULL;
4426 int name;
4427 char *path;
4428
4429 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4430 conv_path_confname, &name)) {
4431 long limit;
4432
4433 errno = 0;
4434 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004435 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004436 if (errno == EINVAL)
4437 /* could be a path or name problem */
4438 posix_error();
4439 else
4440 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004441 }
Fred Drakec9680921999-12-13 16:37:25 +00004442 else
4443 result = PyInt_FromLong(limit);
4444 }
4445 return result;
4446}
4447#endif
4448
4449#ifdef HAVE_CONFSTR
4450static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004451#ifdef _CS_ARCHITECTURE
4452 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4453#endif
4454#ifdef _CS_HOSTNAME
4455 {"CS_HOSTNAME", _CS_HOSTNAME},
4456#endif
4457#ifdef _CS_HW_PROVIDER
4458 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4459#endif
4460#ifdef _CS_HW_SERIAL
4461 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4462#endif
4463#ifdef _CS_INITTAB_NAME
4464 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4465#endif
Fred Drakec9680921999-12-13 16:37:25 +00004466#ifdef _CS_LFS64_CFLAGS
4467 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4468#endif
4469#ifdef _CS_LFS64_LDFLAGS
4470 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4471#endif
4472#ifdef _CS_LFS64_LIBS
4473 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4474#endif
4475#ifdef _CS_LFS64_LINTFLAGS
4476 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4477#endif
4478#ifdef _CS_LFS_CFLAGS
4479 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4480#endif
4481#ifdef _CS_LFS_LDFLAGS
4482 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4483#endif
4484#ifdef _CS_LFS_LIBS
4485 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4486#endif
4487#ifdef _CS_LFS_LINTFLAGS
4488 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4489#endif
Fred Draked86ed291999-12-15 15:34:33 +00004490#ifdef _CS_MACHINE
4491 {"CS_MACHINE", _CS_MACHINE},
4492#endif
Fred Drakec9680921999-12-13 16:37:25 +00004493#ifdef _CS_PATH
4494 {"CS_PATH", _CS_PATH},
4495#endif
Fred Draked86ed291999-12-15 15:34:33 +00004496#ifdef _CS_RELEASE
4497 {"CS_RELEASE", _CS_RELEASE},
4498#endif
4499#ifdef _CS_SRPC_DOMAIN
4500 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4501#endif
4502#ifdef _CS_SYSNAME
4503 {"CS_SYSNAME", _CS_SYSNAME},
4504#endif
4505#ifdef _CS_VERSION
4506 {"CS_VERSION", _CS_VERSION},
4507#endif
Fred Drakec9680921999-12-13 16:37:25 +00004508#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4509 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4510#endif
4511#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4512 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4513#endif
4514#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4515 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4516#endif
4517#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4518 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4519#endif
4520#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4521 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4522#endif
4523#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4524 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4525#endif
4526#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4527 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4528#endif
4529#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4530 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4531#endif
4532#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4533 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4534#endif
4535#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4536 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4537#endif
4538#ifdef _CS_XBS5_LP64_OFF64_LIBS
4539 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4540#endif
4541#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4542 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4543#endif
4544#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4545 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4546#endif
4547#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4548 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4549#endif
4550#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4551 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4552#endif
4553#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4554 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4555#endif
Fred Draked86ed291999-12-15 15:34:33 +00004556#ifdef _MIPS_CS_AVAIL_PROCESSORS
4557 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4558#endif
4559#ifdef _MIPS_CS_BASE
4560 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4561#endif
4562#ifdef _MIPS_CS_HOSTID
4563 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4564#endif
4565#ifdef _MIPS_CS_HW_NAME
4566 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4567#endif
4568#ifdef _MIPS_CS_NUM_PROCESSORS
4569 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4570#endif
4571#ifdef _MIPS_CS_OSREL_MAJ
4572 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4573#endif
4574#ifdef _MIPS_CS_OSREL_MIN
4575 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4576#endif
4577#ifdef _MIPS_CS_OSREL_PATCH
4578 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4579#endif
4580#ifdef _MIPS_CS_OS_NAME
4581 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4582#endif
4583#ifdef _MIPS_CS_OS_PROVIDER
4584 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4585#endif
4586#ifdef _MIPS_CS_PROCESSORS
4587 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4588#endif
4589#ifdef _MIPS_CS_SERIAL
4590 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4591#endif
4592#ifdef _MIPS_CS_VENDOR
4593 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4594#endif
Fred Drakec9680921999-12-13 16:37:25 +00004595};
4596
4597static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004598conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004599{
4600 return conv_confname(arg, valuep, posix_constants_confstr,
4601 sizeof(posix_constants_confstr)
4602 / sizeof(struct constdef));
4603}
4604
4605static char posix_confstr__doc__[] = "\
4606confstr(name) -> string\n\
4607Return a string-valued system configuration variable.";
4608
4609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004610posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004611{
4612 PyObject *result = NULL;
4613 int name;
4614 char buffer[64];
4615
4616 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4617 int len = confstr(name, buffer, sizeof(buffer));
4618
Fred Drakec9680921999-12-13 16:37:25 +00004619 errno = 0;
4620 if (len == 0) {
4621 if (errno != 0)
4622 posix_error();
4623 else
4624 result = PyString_FromString("");
4625 }
4626 else {
4627 if (len >= sizeof(buffer)) {
4628 result = PyString_FromStringAndSize(NULL, len);
4629 if (result != NULL)
4630 confstr(name, PyString_AS_STRING(result), len+1);
4631 }
4632 else
4633 result = PyString_FromString(buffer);
4634 }
4635 }
4636 return result;
4637}
4638#endif
4639
4640
4641#ifdef HAVE_SYSCONF
4642static struct constdef posix_constants_sysconf[] = {
4643#ifdef _SC_2_CHAR_TERM
4644 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4645#endif
4646#ifdef _SC_2_C_BIND
4647 {"SC_2_C_BIND", _SC_2_C_BIND},
4648#endif
4649#ifdef _SC_2_C_DEV
4650 {"SC_2_C_DEV", _SC_2_C_DEV},
4651#endif
4652#ifdef _SC_2_C_VERSION
4653 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4654#endif
4655#ifdef _SC_2_FORT_DEV
4656 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4657#endif
4658#ifdef _SC_2_FORT_RUN
4659 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4660#endif
4661#ifdef _SC_2_LOCALEDEF
4662 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4663#endif
4664#ifdef _SC_2_SW_DEV
4665 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4666#endif
4667#ifdef _SC_2_UPE
4668 {"SC_2_UPE", _SC_2_UPE},
4669#endif
4670#ifdef _SC_2_VERSION
4671 {"SC_2_VERSION", _SC_2_VERSION},
4672#endif
Fred Draked86ed291999-12-15 15:34:33 +00004673#ifdef _SC_ABI_ASYNCHRONOUS_IO
4674 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4675#endif
4676#ifdef _SC_ACL
4677 {"SC_ACL", _SC_ACL},
4678#endif
Fred Drakec9680921999-12-13 16:37:25 +00004679#ifdef _SC_AIO_LISTIO_MAX
4680 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4681#endif
Fred Drakec9680921999-12-13 16:37:25 +00004682#ifdef _SC_AIO_MAX
4683 {"SC_AIO_MAX", _SC_AIO_MAX},
4684#endif
4685#ifdef _SC_AIO_PRIO_DELTA_MAX
4686 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4687#endif
4688#ifdef _SC_ARG_MAX
4689 {"SC_ARG_MAX", _SC_ARG_MAX},
4690#endif
4691#ifdef _SC_ASYNCHRONOUS_IO
4692 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4693#endif
4694#ifdef _SC_ATEXIT_MAX
4695 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4696#endif
Fred Draked86ed291999-12-15 15:34:33 +00004697#ifdef _SC_AUDIT
4698 {"SC_AUDIT", _SC_AUDIT},
4699#endif
Fred Drakec9680921999-12-13 16:37:25 +00004700#ifdef _SC_AVPHYS_PAGES
4701 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4702#endif
4703#ifdef _SC_BC_BASE_MAX
4704 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4705#endif
4706#ifdef _SC_BC_DIM_MAX
4707 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4708#endif
4709#ifdef _SC_BC_SCALE_MAX
4710 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4711#endif
4712#ifdef _SC_BC_STRING_MAX
4713 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4714#endif
Fred Draked86ed291999-12-15 15:34:33 +00004715#ifdef _SC_CAP
4716 {"SC_CAP", _SC_CAP},
4717#endif
Fred Drakec9680921999-12-13 16:37:25 +00004718#ifdef _SC_CHARCLASS_NAME_MAX
4719 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4720#endif
4721#ifdef _SC_CHAR_BIT
4722 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4723#endif
4724#ifdef _SC_CHAR_MAX
4725 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4726#endif
4727#ifdef _SC_CHAR_MIN
4728 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4729#endif
4730#ifdef _SC_CHILD_MAX
4731 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4732#endif
4733#ifdef _SC_CLK_TCK
4734 {"SC_CLK_TCK", _SC_CLK_TCK},
4735#endif
4736#ifdef _SC_COHER_BLKSZ
4737 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4738#endif
4739#ifdef _SC_COLL_WEIGHTS_MAX
4740 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4741#endif
4742#ifdef _SC_DCACHE_ASSOC
4743 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4744#endif
4745#ifdef _SC_DCACHE_BLKSZ
4746 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4747#endif
4748#ifdef _SC_DCACHE_LINESZ
4749 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4750#endif
4751#ifdef _SC_DCACHE_SZ
4752 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4753#endif
4754#ifdef _SC_DCACHE_TBLKSZ
4755 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4756#endif
4757#ifdef _SC_DELAYTIMER_MAX
4758 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4759#endif
4760#ifdef _SC_EQUIV_CLASS_MAX
4761 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4762#endif
4763#ifdef _SC_EXPR_NEST_MAX
4764 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4765#endif
4766#ifdef _SC_FSYNC
4767 {"SC_FSYNC", _SC_FSYNC},
4768#endif
4769#ifdef _SC_GETGR_R_SIZE_MAX
4770 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4771#endif
4772#ifdef _SC_GETPW_R_SIZE_MAX
4773 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4774#endif
4775#ifdef _SC_ICACHE_ASSOC
4776 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4777#endif
4778#ifdef _SC_ICACHE_BLKSZ
4779 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4780#endif
4781#ifdef _SC_ICACHE_LINESZ
4782 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4783#endif
4784#ifdef _SC_ICACHE_SZ
4785 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4786#endif
Fred Draked86ed291999-12-15 15:34:33 +00004787#ifdef _SC_INF
4788 {"SC_INF", _SC_INF},
4789#endif
Fred Drakec9680921999-12-13 16:37:25 +00004790#ifdef _SC_INT_MAX
4791 {"SC_INT_MAX", _SC_INT_MAX},
4792#endif
4793#ifdef _SC_INT_MIN
4794 {"SC_INT_MIN", _SC_INT_MIN},
4795#endif
4796#ifdef _SC_IOV_MAX
4797 {"SC_IOV_MAX", _SC_IOV_MAX},
4798#endif
Fred Draked86ed291999-12-15 15:34:33 +00004799#ifdef _SC_IP_SECOPTS
4800 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4801#endif
Fred Drakec9680921999-12-13 16:37:25 +00004802#ifdef _SC_JOB_CONTROL
4803 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4804#endif
Fred Draked86ed291999-12-15 15:34:33 +00004805#ifdef _SC_KERN_POINTERS
4806 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4807#endif
4808#ifdef _SC_KERN_SIM
4809 {"SC_KERN_SIM", _SC_KERN_SIM},
4810#endif
Fred Drakec9680921999-12-13 16:37:25 +00004811#ifdef _SC_LINE_MAX
4812 {"SC_LINE_MAX", _SC_LINE_MAX},
4813#endif
4814#ifdef _SC_LOGIN_NAME_MAX
4815 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4816#endif
4817#ifdef _SC_LOGNAME_MAX
4818 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4819#endif
4820#ifdef _SC_LONG_BIT
4821 {"SC_LONG_BIT", _SC_LONG_BIT},
4822#endif
Fred Draked86ed291999-12-15 15:34:33 +00004823#ifdef _SC_MAC
4824 {"SC_MAC", _SC_MAC},
4825#endif
Fred Drakec9680921999-12-13 16:37:25 +00004826#ifdef _SC_MAPPED_FILES
4827 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4828#endif
4829#ifdef _SC_MAXPID
4830 {"SC_MAXPID", _SC_MAXPID},
4831#endif
4832#ifdef _SC_MB_LEN_MAX
4833 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4834#endif
4835#ifdef _SC_MEMLOCK
4836 {"SC_MEMLOCK", _SC_MEMLOCK},
4837#endif
4838#ifdef _SC_MEMLOCK_RANGE
4839 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4840#endif
4841#ifdef _SC_MEMORY_PROTECTION
4842 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4843#endif
4844#ifdef _SC_MESSAGE_PASSING
4845 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4846#endif
Fred Draked86ed291999-12-15 15:34:33 +00004847#ifdef _SC_MMAP_FIXED_ALIGNMENT
4848 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4849#endif
Fred Drakec9680921999-12-13 16:37:25 +00004850#ifdef _SC_MQ_OPEN_MAX
4851 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4852#endif
4853#ifdef _SC_MQ_PRIO_MAX
4854 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4855#endif
Fred Draked86ed291999-12-15 15:34:33 +00004856#ifdef _SC_NACLS_MAX
4857 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4858#endif
Fred Drakec9680921999-12-13 16:37:25 +00004859#ifdef _SC_NGROUPS_MAX
4860 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4861#endif
4862#ifdef _SC_NL_ARGMAX
4863 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4864#endif
4865#ifdef _SC_NL_LANGMAX
4866 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4867#endif
4868#ifdef _SC_NL_MSGMAX
4869 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4870#endif
4871#ifdef _SC_NL_NMAX
4872 {"SC_NL_NMAX", _SC_NL_NMAX},
4873#endif
4874#ifdef _SC_NL_SETMAX
4875 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4876#endif
4877#ifdef _SC_NL_TEXTMAX
4878 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4879#endif
4880#ifdef _SC_NPROCESSORS_CONF
4881 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4882#endif
4883#ifdef _SC_NPROCESSORS_ONLN
4884 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4885#endif
Fred Draked86ed291999-12-15 15:34:33 +00004886#ifdef _SC_NPROC_CONF
4887 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4888#endif
4889#ifdef _SC_NPROC_ONLN
4890 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4891#endif
Fred Drakec9680921999-12-13 16:37:25 +00004892#ifdef _SC_NZERO
4893 {"SC_NZERO", _SC_NZERO},
4894#endif
4895#ifdef _SC_OPEN_MAX
4896 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4897#endif
4898#ifdef _SC_PAGESIZE
4899 {"SC_PAGESIZE", _SC_PAGESIZE},
4900#endif
4901#ifdef _SC_PAGE_SIZE
4902 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4903#endif
4904#ifdef _SC_PASS_MAX
4905 {"SC_PASS_MAX", _SC_PASS_MAX},
4906#endif
4907#ifdef _SC_PHYS_PAGES
4908 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4909#endif
4910#ifdef _SC_PII
4911 {"SC_PII", _SC_PII},
4912#endif
4913#ifdef _SC_PII_INTERNET
4914 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4915#endif
4916#ifdef _SC_PII_INTERNET_DGRAM
4917 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4918#endif
4919#ifdef _SC_PII_INTERNET_STREAM
4920 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4921#endif
4922#ifdef _SC_PII_OSI
4923 {"SC_PII_OSI", _SC_PII_OSI},
4924#endif
4925#ifdef _SC_PII_OSI_CLTS
4926 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4927#endif
4928#ifdef _SC_PII_OSI_COTS
4929 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4930#endif
4931#ifdef _SC_PII_OSI_M
4932 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4933#endif
4934#ifdef _SC_PII_SOCKET
4935 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4936#endif
4937#ifdef _SC_PII_XTI
4938 {"SC_PII_XTI", _SC_PII_XTI},
4939#endif
4940#ifdef _SC_POLL
4941 {"SC_POLL", _SC_POLL},
4942#endif
4943#ifdef _SC_PRIORITIZED_IO
4944 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4945#endif
4946#ifdef _SC_PRIORITY_SCHEDULING
4947 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4948#endif
4949#ifdef _SC_REALTIME_SIGNALS
4950 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4951#endif
4952#ifdef _SC_RE_DUP_MAX
4953 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4954#endif
4955#ifdef _SC_RTSIG_MAX
4956 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4957#endif
4958#ifdef _SC_SAVED_IDS
4959 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4960#endif
4961#ifdef _SC_SCHAR_MAX
4962 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4963#endif
4964#ifdef _SC_SCHAR_MIN
4965 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4966#endif
4967#ifdef _SC_SELECT
4968 {"SC_SELECT", _SC_SELECT},
4969#endif
4970#ifdef _SC_SEMAPHORES
4971 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4972#endif
4973#ifdef _SC_SEM_NSEMS_MAX
4974 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4975#endif
4976#ifdef _SC_SEM_VALUE_MAX
4977 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4978#endif
4979#ifdef _SC_SHARED_MEMORY_OBJECTS
4980 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4981#endif
4982#ifdef _SC_SHRT_MAX
4983 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4984#endif
4985#ifdef _SC_SHRT_MIN
4986 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4987#endif
4988#ifdef _SC_SIGQUEUE_MAX
4989 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4990#endif
4991#ifdef _SC_SIGRT_MAX
4992 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4993#endif
4994#ifdef _SC_SIGRT_MIN
4995 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4996#endif
Fred Draked86ed291999-12-15 15:34:33 +00004997#ifdef _SC_SOFTPOWER
4998 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4999#endif
Fred Drakec9680921999-12-13 16:37:25 +00005000#ifdef _SC_SPLIT_CACHE
5001 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5002#endif
5003#ifdef _SC_SSIZE_MAX
5004 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5005#endif
5006#ifdef _SC_STACK_PROT
5007 {"SC_STACK_PROT", _SC_STACK_PROT},
5008#endif
5009#ifdef _SC_STREAM_MAX
5010 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5011#endif
5012#ifdef _SC_SYNCHRONIZED_IO
5013 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5014#endif
5015#ifdef _SC_THREADS
5016 {"SC_THREADS", _SC_THREADS},
5017#endif
5018#ifdef _SC_THREAD_ATTR_STACKADDR
5019 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5020#endif
5021#ifdef _SC_THREAD_ATTR_STACKSIZE
5022 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5023#endif
5024#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5025 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5026#endif
5027#ifdef _SC_THREAD_KEYS_MAX
5028 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5029#endif
5030#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5031 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5032#endif
5033#ifdef _SC_THREAD_PRIO_INHERIT
5034 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5035#endif
5036#ifdef _SC_THREAD_PRIO_PROTECT
5037 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5038#endif
5039#ifdef _SC_THREAD_PROCESS_SHARED
5040 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5041#endif
5042#ifdef _SC_THREAD_SAFE_FUNCTIONS
5043 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5044#endif
5045#ifdef _SC_THREAD_STACK_MIN
5046 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5047#endif
5048#ifdef _SC_THREAD_THREADS_MAX
5049 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5050#endif
5051#ifdef _SC_TIMERS
5052 {"SC_TIMERS", _SC_TIMERS},
5053#endif
5054#ifdef _SC_TIMER_MAX
5055 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5056#endif
5057#ifdef _SC_TTY_NAME_MAX
5058 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5059#endif
5060#ifdef _SC_TZNAME_MAX
5061 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5062#endif
5063#ifdef _SC_T_IOV_MAX
5064 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5065#endif
5066#ifdef _SC_UCHAR_MAX
5067 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5068#endif
5069#ifdef _SC_UINT_MAX
5070 {"SC_UINT_MAX", _SC_UINT_MAX},
5071#endif
5072#ifdef _SC_UIO_MAXIOV
5073 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5074#endif
5075#ifdef _SC_ULONG_MAX
5076 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5077#endif
5078#ifdef _SC_USHRT_MAX
5079 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5080#endif
5081#ifdef _SC_VERSION
5082 {"SC_VERSION", _SC_VERSION},
5083#endif
5084#ifdef _SC_WORD_BIT
5085 {"SC_WORD_BIT", _SC_WORD_BIT},
5086#endif
5087#ifdef _SC_XBS5_ILP32_OFF32
5088 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5089#endif
5090#ifdef _SC_XBS5_ILP32_OFFBIG
5091 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5092#endif
5093#ifdef _SC_XBS5_LP64_OFF64
5094 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5095#endif
5096#ifdef _SC_XBS5_LPBIG_OFFBIG
5097 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5098#endif
5099#ifdef _SC_XOPEN_CRYPT
5100 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5101#endif
5102#ifdef _SC_XOPEN_ENH_I18N
5103 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5104#endif
5105#ifdef _SC_XOPEN_LEGACY
5106 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5107#endif
5108#ifdef _SC_XOPEN_REALTIME
5109 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5110#endif
5111#ifdef _SC_XOPEN_REALTIME_THREADS
5112 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5113#endif
5114#ifdef _SC_XOPEN_SHM
5115 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5116#endif
5117#ifdef _SC_XOPEN_UNIX
5118 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5119#endif
5120#ifdef _SC_XOPEN_VERSION
5121 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5122#endif
5123#ifdef _SC_XOPEN_XCU_VERSION
5124 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5125#endif
5126#ifdef _SC_XOPEN_XPG2
5127 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5128#endif
5129#ifdef _SC_XOPEN_XPG3
5130 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5131#endif
5132#ifdef _SC_XOPEN_XPG4
5133 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5134#endif
5135};
5136
5137static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005138conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005139{
5140 return conv_confname(arg, valuep, posix_constants_sysconf,
5141 sizeof(posix_constants_sysconf)
5142 / sizeof(struct constdef));
5143}
5144
5145static char posix_sysconf__doc__[] = "\
5146sysconf(name) -> integer\n\
5147Return an integer-valued system configuration variable.";
5148
5149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005150posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005151{
5152 PyObject *result = NULL;
5153 int name;
5154
5155 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5156 int value;
5157
5158 errno = 0;
5159 value = sysconf(name);
5160 if (value == -1 && errno != 0)
5161 posix_error();
5162 else
5163 result = PyInt_FromLong(value);
5164 }
5165 return result;
5166}
5167#endif
5168
5169
Fred Drakebec628d1999-12-15 18:31:10 +00005170/* This code is used to ensure that the tables of configuration value names
5171 * are in sorted order as required by conv_confname(), and also to build the
5172 * the exported dictionaries that are used to publish information about the
5173 * names available on the host platform.
5174 *
5175 * Sorting the table at runtime ensures that the table is properly ordered
5176 * when used, even for platforms we're not able to test on. It also makes
5177 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005178 */
Fred Drakebec628d1999-12-15 18:31:10 +00005179
5180static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005181cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005182{
5183 const struct constdef *c1 =
5184 (const struct constdef *) v1;
5185 const struct constdef *c2 =
5186 (const struct constdef *) v2;
5187
5188 return strcmp(c1->name, c2->name);
5189}
5190
5191static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005192setup_confname_table(struct constdef *table, size_t tablesize,
5193 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005194{
Fred Drakebec628d1999-12-15 18:31:10 +00005195 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005196 size_t i;
5197 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005198
5199 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5200 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005201 if (d == NULL)
5202 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005203
Barry Warsaw3155db32000-04-13 15:20:40 +00005204 for (i=0; i < tablesize; ++i) {
5205 PyObject *o = PyInt_FromLong(table[i].value);
5206 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5207 Py_XDECREF(o);
5208 Py_DECREF(d);
5209 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005210 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005211 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005212 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005213 status = PyDict_SetItemString(moddict, tablename, d);
5214 Py_DECREF(d);
5215 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005216}
5217
Fred Drakebec628d1999-12-15 18:31:10 +00005218/* Return -1 on failure, 0 on success. */
5219static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005220setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005221{
5222#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005223 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005224 sizeof(posix_constants_pathconf)
5225 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005226 "pathconf_names", moddict))
5227 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005228#endif
5229#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005230 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005231 sizeof(posix_constants_confstr)
5232 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005233 "confstr_names", moddict))
5234 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005235#endif
5236#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005237 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005238 sizeof(posix_constants_sysconf)
5239 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005240 "sysconf_names", moddict))
5241 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005242#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005243 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005244}
Fred Draked86ed291999-12-15 15:34:33 +00005245
5246
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005247static char posix_abort__doc__[] = "\
5248abort() -> does not return!\n\
5249Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5250in the hardest way possible on the hosting operating system.";
5251
5252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005253posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005254{
5255 if (!PyArg_ParseTuple(args, ":abort"))
5256 return NULL;
5257 abort();
5258 /*NOTREACHED*/
5259 Py_FatalError("abort() called from Python code didn't abort!");
5260 return NULL;
5261}
Fred Drakebec628d1999-12-15 18:31:10 +00005262
Tim Petersf58a7aa2000-09-22 10:05:54 +00005263#ifdef MS_WIN32
5264static char win32_startfile__doc__[] = "\
5265startfile(filepath) - Start a file with its associated application.\n\
5266\n\
5267This acts like double-clicking the file in Explorer, or giving the file\n\
5268name as an argument to the DOS \"start\" command: the file is opened\n\
5269with whatever application (if any) its extension is associated.\n\
5270\n\
5271startfile returns as soon as the associated application is launched.\n\
5272There is no option to wait for the application to close, and no way\n\
5273to retrieve the application's exit status.\n\
5274\n\
5275The filepath is relative to the current directory. If you want to use\n\
5276an absolute path, make sure the first character is not a slash (\"/\");\n\
5277the underlying Win32 ShellExecute function doesn't work if it is.";
5278
5279static PyObject *
5280win32_startfile(PyObject *self, PyObject *args)
5281{
5282 char *filepath;
5283 HINSTANCE rc;
5284 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5285 return NULL;
5286 Py_BEGIN_ALLOW_THREADS
5287 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5288 Py_END_ALLOW_THREADS
5289 if (rc <= (HINSTANCE)32)
5290 return win32_error("startfile", filepath);
5291 Py_INCREF(Py_None);
5292 return Py_None;
5293}
5294#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005295
5296static PyMethodDef posix_methods[] = {
5297 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5298#ifdef HAVE_TTYNAME
5299 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5300#endif
5301 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5302 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005303#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005304 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005305#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005306#ifdef HAVE_CTERMID
5307 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5308#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005309#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005310 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005311#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005312#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005313 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005314#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005315 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5316 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5317 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005318#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005319 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005320#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005321#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005322 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005323#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005324 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5325 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5326 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005327#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005328 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005329#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005330#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005331 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005332#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005333 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005334#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005335 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005336#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005337 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5338 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5339 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005340#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005341 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005342#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005343 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005344#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005345 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5346 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005347#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005348#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005349 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5350 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005351#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005352#ifdef HAVE_FORK1
5353 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5354#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005355#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005356 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005357#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005358#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005359 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005360#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005361#ifdef HAVE_FORKPTY
5362 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5363#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005364#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005365 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005366#endif /* HAVE_GETEGID */
5367#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005368 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005369#endif /* HAVE_GETEUID */
5370#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005371 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005372#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005373#ifdef HAVE_GETGROUPS
5374 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5375#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005376 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005377#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005378 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005379#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005380#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005381 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005382#endif /* HAVE_GETPPID */
5383#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005384 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005385#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005386#ifdef HAVE_GETLOGIN
5387 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5388#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005389#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005390 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005391#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005392#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005393 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005394#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005395#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005396 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005397#ifdef MS_WIN32
5398 {"popen2", win32_popen2, METH_VARARGS},
5399 {"popen3", win32_popen3, METH_VARARGS},
5400 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005401 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005402#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005403#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005404#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005405 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005406#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005407#ifdef HAVE_SETEUID
5408 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5409#endif /* HAVE_SETEUID */
5410#ifdef HAVE_SETEGID
5411 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5412#endif /* HAVE_SETEGID */
5413#ifdef HAVE_SETREUID
5414 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5415#endif /* HAVE_SETREUID */
5416#ifdef HAVE_SETREGID
5417 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5418#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005419#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005420 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005421#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005422#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005423 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005424#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005425#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005426 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005427#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005428#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005429 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005430#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005431#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005432 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005433#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005434#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005435 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005436#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005437#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005438 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005439#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005440#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005441 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005442#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005443 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5444 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5445 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5446 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5447 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5448 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5449 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5450 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5451 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005452 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005453#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005454 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005455#endif
5456#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005457 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005458#endif
5459#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005460 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005461#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005462#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005463 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005464#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005465#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005466 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005467#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005468#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005469 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005470#endif
5471#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005472 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005473#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005474#ifdef HAVE_SYS_WAIT_H
5475#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005476 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005477#endif /* WIFSTOPPED */
5478#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005479 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005480#endif /* WIFSIGNALED */
5481#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005482 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005483#endif /* WIFEXITED */
5484#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005485 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005486#endif /* WEXITSTATUS */
5487#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005488 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005489#endif /* WTERMSIG */
5490#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005491 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005492#endif /* WSTOPSIG */
5493#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005494#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005495 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005496#endif
5497#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005498 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005499#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005500#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005501 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5502#endif
5503#ifdef HAVE_TEMPNAM
5504 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5505#endif
5506#ifdef HAVE_TMPNAM
5507 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5508#endif
Fred Drakec9680921999-12-13 16:37:25 +00005509#ifdef HAVE_CONFSTR
5510 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5511#endif
5512#ifdef HAVE_SYSCONF
5513 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5514#endif
5515#ifdef HAVE_FPATHCONF
5516 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5517#endif
5518#ifdef HAVE_PATHCONF
5519 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5520#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005521 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005522#ifdef MS_WIN32
5523 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5524#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005525 {NULL, NULL} /* Sentinel */
5526};
5527
5528
Barry Warsaw4a342091996-12-19 23:50:02 +00005529static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005530ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005531{
5532 PyObject* v = PyInt_FromLong(value);
5533 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5534 return -1; /* triggers fatal error */
5535
5536 Py_DECREF(v);
5537 return 0;
5538}
5539
Guido van Rossumd48f2521997-12-05 22:19:34 +00005540#if defined(PYOS_OS2)
5541/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5542static int insertvalues(PyObject *d)
5543{
5544 APIRET rc;
5545 ULONG values[QSV_MAX+1];
5546 PyObject *v;
5547 char *ver, tmp[10];
5548
5549 Py_BEGIN_ALLOW_THREADS
5550 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5551 Py_END_ALLOW_THREADS
5552
5553 if (rc != NO_ERROR) {
5554 os2_error(rc);
5555 return -1;
5556 }
5557
5558 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5559 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5560 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5561 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5562 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5563 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5564 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5565
5566 switch (values[QSV_VERSION_MINOR]) {
5567 case 0: ver = "2.00"; break;
5568 case 10: ver = "2.10"; break;
5569 case 11: ver = "2.11"; break;
5570 case 30: ver = "3.00"; break;
5571 case 40: ver = "4.00"; break;
5572 case 50: ver = "5.00"; break;
5573 default:
5574 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5575 values[QSV_VERSION_MINOR]);
5576 ver = &tmp[0];
5577 }
5578
5579 /* Add Indicator of the Version of the Operating System */
5580 v = PyString_FromString(ver);
5581 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5582 return -1;
5583 Py_DECREF(v);
5584
5585 /* Add Indicator of Which Drive was Used to Boot the System */
5586 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5587 tmp[1] = ':';
5588 tmp[2] = '\0';
5589
5590 v = PyString_FromString(tmp);
5591 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5592 return -1;
5593 Py_DECREF(v);
5594
5595 return 0;
5596}
5597#endif
5598
Barry Warsaw4a342091996-12-19 23:50:02 +00005599static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005600all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005601{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005602#ifdef F_OK
5603 if (ins(d, "F_OK", (long)F_OK)) return -1;
5604#endif
5605#ifdef R_OK
5606 if (ins(d, "R_OK", (long)R_OK)) return -1;
5607#endif
5608#ifdef W_OK
5609 if (ins(d, "W_OK", (long)W_OK)) return -1;
5610#endif
5611#ifdef X_OK
5612 if (ins(d, "X_OK", (long)X_OK)) return -1;
5613#endif
Fred Drakec9680921999-12-13 16:37:25 +00005614#ifdef NGROUPS_MAX
5615 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5616#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005617#ifdef TMP_MAX
5618 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5619#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005620#ifdef WNOHANG
5621 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5622#endif
5623#ifdef O_RDONLY
5624 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5625#endif
5626#ifdef O_WRONLY
5627 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5628#endif
5629#ifdef O_RDWR
5630 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5631#endif
5632#ifdef O_NDELAY
5633 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5634#endif
5635#ifdef O_NONBLOCK
5636 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5637#endif
5638#ifdef O_APPEND
5639 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5640#endif
5641#ifdef O_DSYNC
5642 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5643#endif
5644#ifdef O_RSYNC
5645 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5646#endif
5647#ifdef O_SYNC
5648 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5649#endif
5650#ifdef O_NOCTTY
5651 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5652#endif
5653#ifdef O_CREAT
5654 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5655#endif
5656#ifdef O_EXCL
5657 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5658#endif
5659#ifdef O_TRUNC
5660 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5661#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005662#ifdef O_BINARY
5663 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5664#endif
5665#ifdef O_TEXT
5666 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5667#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005668
Guido van Rossum246bc171999-02-01 23:54:31 +00005669#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005670 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5671 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5672 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5673 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5674 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005675#endif
5676
Guido van Rossumd48f2521997-12-05 22:19:34 +00005677#if defined(PYOS_OS2)
5678 if (insertvalues(d)) return -1;
5679#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005680 return 0;
5681}
5682
5683
Tim Peters58e0a8c2001-05-14 22:32:33 +00005684#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005685#define INITFUNC initnt
5686#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005687
5688#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005689#define INITFUNC initos2
5690#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005691
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005692#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005693#define INITFUNC initposix
5694#define MODNAME "posix"
5695#endif
5696
Guido van Rossum3886bb61998-12-04 18:50:17 +00005697DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005698INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005699{
Barry Warsaw53699e91996-12-10 23:23:01 +00005700 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005701
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005702 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005703 posix_methods,
5704 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005705 (PyObject *)NULL,
5706 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005707 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005708
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005709 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005710 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005711 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005712 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005713 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005714
Barry Warsaw4a342091996-12-19 23:50:02 +00005715 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005716 return;
5717
Fred Drakebec628d1999-12-15 18:31:10 +00005718 if (setup_confname_tables(d))
5719 return;
5720
Barry Warsawca74da41999-02-09 19:31:45 +00005721 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005722
Guido van Rossumb3d39562000-01-31 18:41:26 +00005723#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005724 if (posix_putenv_garbage == NULL)
5725 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005726#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005727}