blob: 94630f62988caebd404f852055565f717e18f742 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
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
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000016static char posix__doc__ [] =
17"This module provides access to operating system functionality that is\n\
18standardized by the C Standard and the POSIX standard (a thinly\n\
19disguised Unix interface). Refer to the library manual and\n\
20corresponding Unix manual entries for more information on calls.";
21
Barry Warsaw53699e91996-12-10 23:23:01 +000022#include "Python.h"
Guido van Rossum98bf58f2001-10-18 20:34:25 +000023#include "structseq.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000024
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000025#if defined(PYOS_OS2)
26#define INCL_DOS
27#define INCL_DOSERRORS
28#define INCL_DOSPROCESS
29#define INCL_NOPMAPI
30#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000031#if defined(PYCC_GCC)
32#include <ctype.h>
33#include <io.h>
34#include <stdio.h>
35#include <process.h>
36#include "osdefs.h"
37#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000038#endif
39
Guido van Rossumb6775db1994-08-01 11:34:53 +000040#include <sys/types.h>
41#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000042
Guido van Rossum36bc6801995-06-14 22:54:23 +000043#ifdef HAVE_SYS_WAIT_H
44#include <sys/wait.h> /* For WNOHANG */
45#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000046
Guido van Rossuma376cc51996-12-05 23:43:35 +000047#ifdef HAVE_SIGNAL_H
48#include <signal.h>
49#endif
50
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#ifdef HAVE_FCNTL_H
52#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000053#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000054
Guido van Rossuma6535fd2001-10-18 19:44:10 +000055#ifdef HAVE_GRP_H
56#include <grp.h>
57#endif
58
Guido van Rossuma4916fa1996-05-23 22:58:55 +000059/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000060/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000062#include <process.h>
63#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000064#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000065#define HAVE_GETCWD 1
66#define HAVE_OPENDIR 1
67#define HAVE_SYSTEM 1
68#if defined(__OS2__)
69#define HAVE_EXECV 1
70#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000071#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072#include <process.h>
73#else
74#ifdef __BORLANDC__ /* Borland compiler */
75#define HAVE_EXECV 1
76#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#define HAVE_OPENDIR 1
78#define HAVE_PIPE 1
79#define HAVE_POPEN 1
80#define HAVE_SYSTEM 1
81#define HAVE_WAIT 1
82#else
83#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000084#define HAVE_GETCWD 1
85#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000086#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000087#define HAVE_EXECV 1
88#define HAVE_PIPE 1
89#define HAVE_POPEN 1
90#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000091#define HAVE_CWAIT 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000093#endif /* !MS_WIN32 */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000094#else
95#if defined(PYOS_OS2) && defined(PYCC_GCC)
96/* Everything needed is defined in PC/os2emx/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000097#else /* all other compilers */
98/* Unix functions that the configure script doesn't check for */
99#define HAVE_EXECV 1
100#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000101#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
102#define HAVE_FORK1 1
103#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000104#define HAVE_GETCWD 1
105#define HAVE_GETEGID 1
106#define HAVE_GETEUID 1
107#define HAVE_GETGID 1
108#define HAVE_GETPPID 1
109#define HAVE_GETUID 1
110#define HAVE_KILL 1
111#define HAVE_OPENDIR 1
112#define HAVE_PIPE 1
113#define HAVE_POPEN 1
114#define HAVE_SYSTEM 1
115#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000116#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000117#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#endif /* _MSC_VER */
119#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000120#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000121#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000122
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000123#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000124
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000125#if defined(sun) && !defined(__SVR4)
126/* SunOS 4.1.4 doesn't have prototypes for these: */
127extern int rename(const char *, const char *);
128extern int pclose(FILE *);
129extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000130extern int fsync(int);
131extern int lstat(const char *, struct stat *);
132extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000133#endif
134
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000135#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000136#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000138#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000139#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000142extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000144#endif
145#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(char *);
147extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(const char *);
150extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000152#ifdef __BORLANDC__
153extern int chmod(const char *, int);
154#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000156#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int chown(const char *, uid_t, gid_t);
158extern char *getcwd(char *, int);
159extern char *strerror(int);
160extern int link(const char *, const char *);
161extern int rename(const char *, const char *);
162extern int stat(const char *, struct stat *);
163extern int unlink(const char *);
164extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000167#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000170#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000172
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175#ifdef HAVE_UTIME_H
176#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000177#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000179#ifdef HAVE_SYS_UTIME_H
180#include <sys/utime.h>
181#define HAVE_UTIME_H /* pretend we do for the rest of this file */
182#endif /* HAVE_SYS_UTIME_H */
183
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184#ifdef HAVE_SYS_TIMES_H
185#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000186#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187
188#ifdef HAVE_SYS_PARAM_H
189#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000190#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000191
192#ifdef HAVE_SYS_UTSNAME_H
193#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000194#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000196#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000198#define NAMLEN(dirent) strlen((dirent)->d_name)
199#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000200#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#include <direct.h>
202#define NAMLEN(dirent) strlen((dirent)->d_name)
203#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000206#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000207#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#include <direct.h>
220#include <io.h>
221#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000222#include "osdefs.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
Tim Petersbc2e10e2002-03-03 23:17:02 +0000238#ifndef MAXPATHLEN
239#define MAXPATHLEN 1024
240#endif /* MAXPATHLEN */
241
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000242#ifdef UNION_WAIT
243/* Emulate some macros on systems that have a union instead of macros */
244
245#ifndef WIFEXITED
246#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
247#endif
248
249#ifndef WEXITSTATUS
250#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
251#endif
252
253#ifndef WTERMSIG
254#define WTERMSIG(u_wait) ((u_wait).w_termsig)
255#endif
256
257#endif /* UNION_WAIT */
258
Greg Wardb48bc172000-03-01 21:51:56 +0000259/* Don't use the "_r" form if we don't need it (also, won't have a
260 prototype for it, at least on Solaris -- maybe others as well?). */
261#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
262#define USE_CTERMID_R
263#endif
264
265#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
266#define USE_TMPNAM_R
267#endif
268
Fred Drake699f3522000-06-29 21:12:41 +0000269/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000270#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000271#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000272# define STAT _stati64
273# define FSTAT _fstati64
274# define STRUCT_STAT struct _stati64
275#else
276# define STAT stat
277# define FSTAT fstat
278# define STRUCT_STAT struct stat
279#endif
280
281
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282/* Return a dictionary corresponding to the POSIX environment table */
283
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000284#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000286#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287
Barry Warsaw53699e91996-12-10 23:23:01 +0000288static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000289convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290{
Barry Warsaw53699e91996-12-10 23:23:01 +0000291 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000293 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 if (d == NULL)
295 return NULL;
296 if (environ == NULL)
297 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000298 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000300 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000301 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 char *p = strchr(*e, '=');
303 if (p == NULL)
304 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000305 k = PyString_FromStringAndSize(*e, (int)(p-*e));
306 if (k == NULL) {
307 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000309 }
310 v = PyString_FromString(p+1);
311 if (v == NULL) {
312 PyErr_Clear();
313 Py_DECREF(k);
314 continue;
315 }
316 if (PyDict_GetItem(d, k) == NULL) {
317 if (PyDict_SetItem(d, k, v) != 0)
318 PyErr_Clear();
319 }
320 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000321 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000323#if defined(PYOS_OS2)
324 {
325 APIRET rc;
326 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
327
328 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000329 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000330 PyObject *v = PyString_FromString(buffer);
331 PyDict_SetItemString(d, "BEGINLIBPATH", v);
332 Py_DECREF(v);
333 }
334 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
335 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
336 PyObject *v = PyString_FromString(buffer);
337 PyDict_SetItemString(d, "ENDLIBPATH", v);
338 Py_DECREF(v);
339 }
340 }
341#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342 return d;
343}
344
345
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346/* Set a POSIX-specific error from errno, and return NULL */
347
Barry Warsawd58d7641998-07-23 16:14:40 +0000348static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000349posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000350{
Barry Warsawca74da41999-02-09 19:31:45 +0000351 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000352}
Barry Warsawd58d7641998-07-23 16:14:40 +0000353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000354posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000355{
Barry Warsawca74da41999-02-09 19:31:45 +0000356 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000357}
358
Mark Hammondef8b6542001-05-13 08:04:26 +0000359static PyObject *
360posix_error_with_allocated_filename(char* name)
361{
362 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
363 PyMem_Free(name);
364 return rc;
365}
366
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000367#ifdef MS_WIN32
368static PyObject *
369win32_error(char* function, char* filename)
370{
Mark Hammond33a6da92000-08-15 00:46:38 +0000371 /* XXX We should pass the function name along in the future.
372 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000373 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000374 Windows error object, which is non-trivial.
375 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000376 errno = GetLastError();
377 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000378 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000379 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000380 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000381}
382#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000383
Guido van Rossumd48f2521997-12-05 22:19:34 +0000384#if defined(PYOS_OS2)
385/**********************************************************************
386 * Helper Function to Trim and Format OS/2 Messages
387 **********************************************************************/
388 static void
389os2_formatmsg(char *msgbuf, int msglen, char *reason)
390{
391 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
392
393 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
394 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
395
396 while (lastc > msgbuf && isspace(*lastc))
397 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
398 }
399
400 /* Add Optional Reason Text */
401 if (reason) {
402 strcat(msgbuf, " : ");
403 strcat(msgbuf, reason);
404 }
405}
406
407/**********************************************************************
408 * Decode an OS/2 Operating System Error Code
409 *
410 * A convenience function to lookup an OS/2 error code and return a
411 * text message we can use to raise a Python exception.
412 *
413 * Notes:
414 * The messages for errors returned from the OS/2 kernel reside in
415 * the file OSO001.MSG in the \OS2 directory hierarchy.
416 *
417 **********************************************************************/
418 static char *
419os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
420{
421 APIRET rc;
422 ULONG msglen;
423
424 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
425 Py_BEGIN_ALLOW_THREADS
426 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
427 errorcode, "oso001.msg", &msglen);
428 Py_END_ALLOW_THREADS
429
430 if (rc == NO_ERROR)
431 os2_formatmsg(msgbuf, msglen, reason);
432 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000433 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000434 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000435
436 return msgbuf;
437}
438
439/* Set an OS/2-specific error and return NULL. OS/2 kernel
440 errors are not in a global variable e.g. 'errno' nor are
441 they congruent with posix error numbers. */
442
443static PyObject * os2_error(int code)
444{
445 char text[1024];
446 PyObject *v;
447
448 os2_strerror(text, sizeof(text), code, "");
449
450 v = Py_BuildValue("(is)", code, text);
451 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000452 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000453 Py_DECREF(v);
454 }
455 return NULL; /* Signal to Python that an Exception is Pending */
456}
457
458#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459
460/* POSIX generic methods */
461
Barry Warsaw53699e91996-12-10 23:23:01 +0000462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000463posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000464{
465 int fd;
466 int res;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000467 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000468 return NULL;
469 Py_BEGIN_ALLOW_THREADS
470 res = (*func)(fd);
471 Py_END_ALLOW_THREADS
472 if (res < 0)
473 return posix_error();
474 Py_INCREF(Py_None);
475 return Py_None;
476}
477
Fred Drake4d1e64b2002-04-15 19:40:07 +0000478static PyObject *
479posix_fildes(PyObject *fdobj, int (*func)(int))
480{
481 int fd;
482 int res;
483 fd = PyObject_AsFileDescriptor(fdobj);
484 if (fd < 0)
485 return NULL;
486 Py_BEGIN_ALLOW_THREADS
487 res = (*func)(fd);
488 Py_END_ALLOW_THREADS
489 if (res < 0)
490 return posix_error();
491 Py_INCREF(Py_None);
492 return Py_None;
493}
Guido van Rossum21142a01999-01-08 21:05:37 +0000494
495static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000496posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497{
Mark Hammondef8b6542001-05-13 08:04:26 +0000498 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000499 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000500 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000501 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000503 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000504 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000505 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000506 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000507 return posix_error_with_allocated_filename(path1);
508 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000509 Py_INCREF(Py_None);
510 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511}
512
Barry Warsaw53699e91996-12-10 23:23:01 +0000513static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000514posix_2str(PyObject *args, char *format,
515 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000516{
Mark Hammondef8b6542001-05-13 08:04:26 +0000517 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000518 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000519 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000520 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000521 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000522 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000523 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000524 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000525 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000526 PyMem_Free(path1);
527 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000528 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000529 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000530 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000531 Py_INCREF(Py_None);
532 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000533}
534
Tim Peters5aa91602002-01-30 05:46:57 +0000535static char stat_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000536"stat_result: Result from stat or lstat.\n\n\
537This object may be accessed either as a tuple of\n\
538 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
539or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
540\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000541Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000542they are available as attributes only.\n\
543\n\
544See os.stat for more information.\n";
545
546static PyStructSequence_Field stat_result_fields[] = {
547 {"st_mode", "protection bits"},
548 {"st_ino", "inode"},
549 {"st_dev", "device"},
550 {"st_nlink", "number of hard links"},
551 {"st_uid", "user ID of owner"},
552 {"st_gid", "group ID of owner"},
553 {"st_size", "total size, in bytes"},
554 {"st_atime", "time of last access"},
555 {"st_mtime", "time of last modification"},
556 {"st_ctime", "time of last change"},
557#ifdef HAVE_ST_BLKSIZE
558 {"st_blksize", "blocksize for filesystem I/O"},
559#endif
560#ifdef HAVE_ST_BLOCKS
561 {"st_blocks", "number of blocks allocated"},
562#endif
563#ifdef HAVE_ST_RDEV
564 {"st_rdev", "device type (if inode device)"},
565#endif
566 {0}
567};
568
569#ifdef HAVE_ST_BLKSIZE
570#define ST_BLKSIZE_IDX 10
571#else
572#define ST_BLKSIZE_IDX 9
573#endif
574
575#ifdef HAVE_ST_BLOCKS
576#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
577#else
578#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
579#endif
580
581#ifdef HAVE_ST_RDEV
582#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
583#else
584#define ST_RDEV_IDX ST_BLOCKS_IDX
585#endif
586
587static PyStructSequence_Desc stat_result_desc = {
588 "stat_result", /* name */
589 stat_result__doc__, /* doc */
590 stat_result_fields,
591 10
592};
593
Tim Peters5aa91602002-01-30 05:46:57 +0000594static char statvfs_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000595"statvfs_result: Result from statvfs or fstatvfs.\n\n\
596This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000597 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
598or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000599\n\
600See os.statvfs for more information.\n";
601
602static PyStructSequence_Field statvfs_result_fields[] = {
603 {"f_bsize", },
604 {"f_frsize", },
605 {"f_blocks", },
606 {"f_bfree", },
607 {"f_bavail", },
608 {"f_files", },
609 {"f_ffree", },
610 {"f_favail", },
611 {"f_flag", },
612 {"f_namemax",},
613 {0}
614};
615
616static PyStructSequence_Desc statvfs_result_desc = {
617 "statvfs_result", /* name */
618 statvfs_result__doc__, /* doc */
619 statvfs_result_fields,
620 10
621};
622
623static PyTypeObject StatResultType;
624static PyTypeObject StatVFSResultType;
625
Tim Peters5aa91602002-01-30 05:46:57 +0000626/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000627 (used by posix_stat() and posix_fstat()) */
628static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000629_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000630{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000631 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000632 if (v == NULL)
633 return NULL;
634
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000635 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000636#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000637 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000638 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000639#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000640 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000641#endif
642#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000643 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000644 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000645#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000646 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000647#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000648 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
649 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
650 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000651#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000652 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000653 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000654#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000655 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000656#endif
657#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000658 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000659 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000660 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000661 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000662 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000663 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000664#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000665 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
666 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
667 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
668#endif
669
670#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000671 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000672 PyInt_FromLong((long)st.st_blksize));
673#endif
674#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000675 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000676 PyInt_FromLong((long)st.st_blocks));
677#endif
678#ifdef HAVE_ST_RDEV
679 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
680 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000681#endif
682
683 if (PyErr_Occurred()) {
684 Py_DECREF(v);
685 return NULL;
686 }
687
688 return v;
689}
690
Barry Warsaw53699e91996-12-10 23:23:01 +0000691static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000692posix_do_stat(PyObject *self, PyObject *args, char *format,
693 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694{
Fred Drake699f3522000-06-29 21:12:41 +0000695 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000696 char *path = NULL; /* pass this to stat; do not free() it */
697 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000698 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000699
700#ifdef MS_WIN32
Tim Peters500bd032001-12-19 19:05:01 +0000701 int pathlen;
702 char pathcopy[MAX_PATH];
Guido van Rossumace88ae2000-04-21 18:54:45 +0000703#endif /* MS_WIN32 */
704
Tim Peters5aa91602002-01-30 05:46:57 +0000705 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000706 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000707 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000708 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000709
710#ifdef MS_WIN32
711 pathlen = strlen(path);
712 /* the library call can blow up if the file name is too long! */
713 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000714 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000715 errno = ENAMETOOLONG;
716 return posix_error();
717 }
718
Tim Peters500bd032001-12-19 19:05:01 +0000719 /* Remove trailing slash or backslash, unless it's the current
720 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
721 */
722 if (pathlen > 0 &&
723 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
724 /* It does end with a slash -- exempt the root drive cases. */
725 /* XXX UNC root drives should also be exempted? */
726 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
727 /* leave it alone */;
728 else {
729 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000730 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000731 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000732 path = pathcopy;
733 }
734 }
735#endif /* MS_WIN32 */
736
Barry Warsaw53699e91996-12-10 23:23:01 +0000737 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000738 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000739 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000740 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000741 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000742
Tim Peters500bd032001-12-19 19:05:01 +0000743 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000744 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000745}
746
747
748/* POSIX methods */
749
Guido van Rossum94f6f721999-01-06 18:42:14 +0000750static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000751"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000752Test for access to a file.";
753
754static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000755posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000756{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000757 char *path;
758 int mode;
759 int res;
760
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000761 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000762 return NULL;
763 Py_BEGIN_ALLOW_THREADS
764 res = access(path, mode);
765 Py_END_ALLOW_THREADS
766 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000767}
768
Guido van Rossumd371ff11999-01-25 16:12:23 +0000769#ifndef F_OK
770#define F_OK 0
771#endif
772#ifndef R_OK
773#define R_OK 4
774#endif
775#ifndef W_OK
776#define W_OK 2
777#endif
778#ifndef X_OK
779#define X_OK 1
780#endif
781
782#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000783static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000784"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000785Return the name of the terminal device connected to 'fd'.";
786
787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000788posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000789{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000790 int id;
791 char *ret;
792
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000793 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000794 return NULL;
795
Guido van Rossum94f6f721999-01-06 18:42:14 +0000796 ret = ttyname(id);
797 if (ret == NULL)
798 return(posix_error());
799 return(PyString_FromString(ret));
800}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000801#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000802
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000803#ifdef HAVE_CTERMID
804static char posix_ctermid__doc__[] =
805"ctermid() -> String\n\
806Return the name of the controlling terminal for this process.";
807
808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000809posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000810{
811 char *ret;
812 char buffer[L_ctermid];
813
814 if (!PyArg_ParseTuple(args, ":ctermid"))
815 return NULL;
816
Greg Wardb48bc172000-03-01 21:51:56 +0000817#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000818 ret = ctermid_r(buffer);
819#else
820 ret = ctermid(buffer);
821#endif
822 if (ret == NULL)
823 return(posix_error());
824 return(PyString_FromString(buffer));
825}
826#endif
827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000828static char posix_chdir__doc__[] =
829"chdir(path) -> None\n\
830Change the current working directory to the specified path.";
831
Barry Warsaw53699e91996-12-10 23:23:01 +0000832static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000833posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000834{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000835#if defined(PYOS_OS2) && defined(PYCC_GCC)
836 return posix_1str(args, "et:chdir", _chdir2);
837#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000838 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000839#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000840}
841
Fred Drake4d1e64b2002-04-15 19:40:07 +0000842#ifdef HAVE_FCHDIR
843static char posix_fchdir__doc__[] =
844"fchdir(fildes) -> None\n\
845Change to the directory of the given file descriptor. fildes must be\n\
846opened on a directory, not a file.";
847
848static PyObject *
849posix_fchdir(PyObject *self, PyObject *fdobj)
850{
851 return posix_fildes(fdobj, fchdir);
852}
853#endif /* HAVE_FCHDIR */
854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000855
856static char posix_chmod__doc__[] =
857"chmod(path, mode) -> None\n\
858Change the access permissions of a file.";
859
Barry Warsaw53699e91996-12-10 23:23:01 +0000860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000861posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000862{
Mark Hammondef8b6542001-05-13 08:04:26 +0000863 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000864 int i;
865 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000866 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000867 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000868 return NULL;
869 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000870 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000871 Py_END_ALLOW_THREADS
872 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000873 return posix_error_with_allocated_filename(path);
874 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000875 Py_INCREF(Py_None);
876 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000877}
878
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000879
Martin v. Löwis244edc82001-10-04 22:44:26 +0000880#ifdef HAVE_CHROOT
Tim Peters5aa91602002-01-30 05:46:57 +0000881static char posix_chroot__doc__[] =
Martin v. Löwis244edc82001-10-04 22:44:26 +0000882"chroot(path) -> None\n\
883Change root directory to path.";
884
885static PyObject *
886posix_chroot(PyObject *self, PyObject *args)
887{
888 return posix_1str(args, "et:chroot", chroot);
889}
890#endif
891
Guido van Rossum21142a01999-01-08 21:05:37 +0000892#ifdef HAVE_FSYNC
893static char posix_fsync__doc__[] =
894"fsync(fildes) -> None\n\
895force write of file with filedescriptor to disk.";
896
897static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000898posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000899{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000900 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000901}
902#endif /* HAVE_FSYNC */
903
904#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000905
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000906#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000907extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
908#endif
909
Guido van Rossum21142a01999-01-08 21:05:37 +0000910static char posix_fdatasync__doc__[] =
911"fdatasync(fildes) -> None\n\
912force write of file with filedescriptor to disk.\n\
913 does not force update of metadata.";
914
915static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000916posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000917{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000918 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000919}
920#endif /* HAVE_FDATASYNC */
921
922
Fredrik Lundh10723342000-07-10 16:38:09 +0000923#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000924static char posix_chown__doc__[] =
925"chown(path, uid, gid) -> None\n\
926Change the owner and group id of path to the numeric uid and gid.";
927
Barry Warsaw53699e91996-12-10 23:23:01 +0000928static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000929posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000930{
Mark Hammondef8b6542001-05-13 08:04:26 +0000931 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000932 int uid, gid;
933 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000934 if (!PyArg_ParseTuple(args, "etii:chown",
935 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000936 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000937 return NULL;
938 Py_BEGIN_ALLOW_THREADS
939 res = chown(path, (uid_t) uid, (gid_t) gid);
940 Py_END_ALLOW_THREADS
941 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000942 return posix_error_with_allocated_filename(path);
943 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000944 Py_INCREF(Py_None);
945 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000946}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000947#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000949
Guido van Rossum36bc6801995-06-14 22:54:23 +0000950#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000951static char posix_getcwd__doc__[] =
952"getcwd() -> path\n\
953Return a string representing the current working directory.";
954
Barry Warsaw53699e91996-12-10 23:23:01 +0000955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000956posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000957{
958 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000959 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000960 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000961 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000962 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000963#if defined(PYOS_OS2) && defined(PYCC_GCC)
964 res = _getcwd2(buf, sizeof buf);
965#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000966 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000967#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000968 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000969 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000970 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000971 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000972}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000973#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000975
Guido van Rossumb6775db1994-08-01 11:34:53 +0000976#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000977static char posix_link__doc__[] =
978"link(src, dst) -> None\n\
979Create a hard link to a file.";
980
Barry Warsaw53699e91996-12-10 23:23:01 +0000981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000982posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000983{
Mark Hammondef8b6542001-05-13 08:04:26 +0000984 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000986#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000988
989static char posix_listdir__doc__[] =
990"listdir(path) -> list_of_strings\n\
991Return a list containing the names of the entries in the directory.\n\
992\n\
993 path: path of directory to list\n\
994\n\
995The list is in arbitrary order. It does not include the special\n\
996entries '.' and '..' even if they are present in the directory.";
997
Barry Warsaw53699e91996-12-10 23:23:01 +0000998static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000999posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001000{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001001 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001002 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +00001003#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001004
Barry Warsaw53699e91996-12-10 23:23:01 +00001005 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001006 HANDLE hFindFile;
1007 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001008 /* MAX_PATH characters could mean a bigger encoded string */
1009 char namebuf[MAX_PATH*2+5];
1010 char *bufptr = namebuf;
1011 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001012
Tim Peters5aa91602002-01-30 05:46:57 +00001013 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001014 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001015 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001016 if (len > 0) {
1017 char ch = namebuf[len-1];
1018 if (ch != SEP && ch != ALTSEP && ch != ':')
1019 namebuf[len++] = '/';
1020 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001021 strcpy(namebuf + len, "*.*");
1022
Barry Warsaw53699e91996-12-10 23:23:01 +00001023 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001024 return NULL;
1025
1026 hFindFile = FindFirstFile(namebuf, &FileData);
1027 if (hFindFile == INVALID_HANDLE_VALUE) {
1028 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001029 if (errno == ERROR_FILE_NOT_FOUND)
1030 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001031 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001032 }
1033 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001034 if (FileData.cFileName[0] == '.' &&
1035 (FileData.cFileName[1] == '\0' ||
1036 FileData.cFileName[1] == '.' &&
1037 FileData.cFileName[2] == '\0'))
1038 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001039 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001040 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001041 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001042 d = NULL;
1043 break;
1044 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001045 if (PyList_Append(d, v) != 0) {
1046 Py_DECREF(v);
1047 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001048 d = NULL;
1049 break;
1050 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001051 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001052 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1053
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001054 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001055 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001056
1057 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001058
Tim Peters0bb44a42000-09-15 07:44:49 +00001059#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001060
1061#ifndef MAX_PATH
1062#define MAX_PATH 250
1063#endif
1064 char *name, *pt;
1065 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001066 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001067 char namebuf[MAX_PATH+5];
1068 struct _find_t ep;
1069
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001070 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001071 return NULL;
1072 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001073 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001074 return NULL;
1075 }
1076 strcpy(namebuf, name);
1077 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001078 if (*pt == ALTSEP)
1079 *pt = SEP;
1080 if (namebuf[len-1] != SEP)
1081 namebuf[len++] = SEP;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001082 strcpy(namebuf + len, "*.*");
1083
Barry Warsaw53699e91996-12-10 23:23:01 +00001084 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001085 return NULL;
1086
1087 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001088 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1089 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001090 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001091 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001092 }
1093 do {
1094 if (ep.name[0] == '.' &&
1095 (ep.name[1] == '\0' ||
1096 ep.name[1] == '.' &&
1097 ep.name[2] == '\0'))
1098 continue;
1099 strcpy(namebuf, ep.name);
1100 for (pt = namebuf; *pt; pt++)
1101 if (isupper(*pt))
1102 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001103 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001104 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001105 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001106 d = NULL;
1107 break;
1108 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001109 if (PyList_Append(d, v) != 0) {
1110 Py_DECREF(v);
1111 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001112 d = NULL;
1113 break;
1114 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001115 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001116 } while (_dos_findnext(&ep) == 0);
1117
1118 return d;
1119
Tim Peters0bb44a42000-09-15 07:44:49 +00001120#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001121
1122#ifndef MAX_PATH
1123#define MAX_PATH CCHMAXPATH
1124#endif
1125 char *name, *pt;
1126 int len;
1127 PyObject *d, *v;
1128 char namebuf[MAX_PATH+5];
1129 HDIR hdir = 1;
1130 ULONG srchcnt = 1;
1131 FILEFINDBUF3 ep;
1132 APIRET rc;
1133
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001134 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001135 return NULL;
1136 if (len >= MAX_PATH) {
1137 PyErr_SetString(PyExc_ValueError, "path too long");
1138 return NULL;
1139 }
1140 strcpy(namebuf, name);
1141 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001142 if (*pt == ALTSEP)
1143 *pt = SEP;
1144 if (namebuf[len-1] != SEP)
1145 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001146 strcpy(namebuf + len, "*.*");
1147
1148 if ((d = PyList_New(0)) == NULL)
1149 return NULL;
1150
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001151 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1152 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001153 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001154 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1155 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1156 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001157
1158 if (rc != NO_ERROR) {
1159 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001160 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001161 }
1162
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001163 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001164 do {
1165 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001166 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001167 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001168
1169 strcpy(namebuf, ep.achName);
1170
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001171 /* Leave Case of Name Alone -- In Native Form */
1172 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001173
1174 v = PyString_FromString(namebuf);
1175 if (v == NULL) {
1176 Py_DECREF(d);
1177 d = NULL;
1178 break;
1179 }
1180 if (PyList_Append(d, v) != 0) {
1181 Py_DECREF(v);
1182 Py_DECREF(d);
1183 d = NULL;
1184 break;
1185 }
1186 Py_DECREF(v);
1187 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1188 }
1189
1190 return d;
1191#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001192
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001193 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001194 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001196 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001197 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001198 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001199 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001200 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001201 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001202 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001203 closedir(dirp);
1204 return NULL;
1205 }
1206 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001207 if (ep->d_name[0] == '.' &&
1208 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001209 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001210 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001211 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001212 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001213 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214 d = NULL;
1215 break;
1216 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001217 if (PyList_Append(d, v) != 0) {
1218 Py_DECREF(v);
1219 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001220 d = NULL;
1221 break;
1222 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001223 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001224 }
1225 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001226
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001227 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001228
Tim Peters0bb44a42000-09-15 07:44:49 +00001229#endif /* which OS */
1230} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001231
Mark Hammondef8b6542001-05-13 08:04:26 +00001232#ifdef MS_WIN32
1233/* A helper function for abspath on win32 */
1234static PyObject *
1235posix__getfullpathname(PyObject *self, PyObject *args)
1236{
1237 /* assume encoded strings wont more than double no of chars */
1238 char inbuf[MAX_PATH*2];
1239 char *inbufp = inbuf;
1240 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1241 char outbuf[MAX_PATH*2];
1242 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001243 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1244 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001245 &insize))
1246 return NULL;
1247 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1248 outbuf, &temp))
1249 return win32_error("GetFullPathName", inbuf);
1250 return PyString_FromString(outbuf);
1251} /* end of posix__getfullpathname */
1252#endif /* MS_WIN32 */
1253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001254static char posix_mkdir__doc__[] =
1255"mkdir(path [, mode=0777]) -> None\n\
1256Create a directory.";
1257
Barry Warsaw53699e91996-12-10 23:23:01 +00001258static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001259posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001260{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001261 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001262 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001263 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001264 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001265 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001266 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001267 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001268#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001269 res = mkdir(path);
1270#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001271 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001272#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001273 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001274 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001275 return posix_error_with_allocated_filename(path);
1276 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001277 Py_INCREF(Py_None);
1278 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001279}
1280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001281
Guido van Rossumb6775db1994-08-01 11:34:53 +00001282#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001283#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1284#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1285#include <sys/resource.h>
1286#endif
1287#endif
1288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001289static char posix_nice__doc__[] =
1290"nice(inc) -> new_priority\n\
1291Decrease the priority of process and return new priority.";
1292
Barry Warsaw53699e91996-12-10 23:23:01 +00001293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001294posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001295{
1296 int increment, value;
1297
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001298 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001299 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001300
1301 /* There are two flavours of 'nice': one that returns the new
1302 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001303 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1304 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001305
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001306 If we are of the nice family that returns the new priority, we
1307 need to clear errno before the call, and check if errno is filled
1308 before calling posix_error() on a returnvalue of -1, because the
1309 -1 may be the actual new priority! */
1310
1311 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001312 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001313#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001314 if (value == 0)
1315 value = getpriority(PRIO_PROCESS, 0);
1316#endif
1317 if (value == -1 && errno != 0)
1318 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001319 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001320 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001321}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001322#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001324
1325static char posix_rename__doc__[] =
1326"rename(old, new) -> None\n\
1327Rename a file or directory.";
1328
Barry Warsaw53699e91996-12-10 23:23:01 +00001329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001330posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331{
Mark Hammondef8b6542001-05-13 08:04:26 +00001332 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333}
1334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
1336static char posix_rmdir__doc__[] =
1337"rmdir(path) -> None\n\
1338Remove a directory.";
1339
Barry Warsaw53699e91996-12-10 23:23:01 +00001340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001341posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342{
Mark Hammondef8b6542001-05-13 08:04:26 +00001343 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344}
1345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001346
1347static char posix_stat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00001348"stat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
1349 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001350Perform a stat system call on the given path.";
1351
Barry Warsaw53699e91996-12-10 23:23:01 +00001352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001353posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001354{
Mark Hammondef8b6542001-05-13 08:04:26 +00001355 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001356}
1357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001358
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001359#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001360static char posix_system__doc__[] =
1361"system(command) -> exit_status\n\
1362Execute the command (a string) in a subshell.";
1363
Barry Warsaw53699e91996-12-10 23:23:01 +00001364static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001365posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001366{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001367 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001368 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001369 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001370 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001371 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001372 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001373 Py_END_ALLOW_THREADS
1374 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001375}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001376#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001377
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001378
1379static char posix_umask__doc__[] =
1380"umask(new_mask) -> old_mask\n\
1381Set the current numeric umask and return the previous umask.";
1382
Barry Warsaw53699e91996-12-10 23:23:01 +00001383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001384posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001385{
1386 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001387 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001388 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001389 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390 if (i < 0)
1391 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001392 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393}
1394
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001395
1396static char posix_unlink__doc__[] =
1397"unlink(path) -> None\n\
1398Remove a file (same as remove(path)).";
1399
1400static char posix_remove__doc__[] =
1401"remove(path) -> None\n\
1402Remove a file (same as unlink(path)).";
1403
Barry Warsaw53699e91996-12-10 23:23:01 +00001404static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001405posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001406{
Mark Hammondef8b6542001-05-13 08:04:26 +00001407 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001408}
1409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001410
Guido van Rossumb6775db1994-08-01 11:34:53 +00001411#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001412static char posix_uname__doc__[] =
1413"uname() -> (sysname, nodename, release, version, machine)\n\
1414Return a tuple identifying the current operating system.";
1415
Barry Warsaw53699e91996-12-10 23:23:01 +00001416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001417posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001418{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001419 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001420 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001421 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001422 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001423 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001424 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001425 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001426 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001427 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001428 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001429 u.sysname,
1430 u.nodename,
1431 u.release,
1432 u.version,
1433 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001434}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001435#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001436
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001437
1438static char posix_utime__doc__[] =
1439"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001440utime(path, None) -> None\n\
1441Set the access and modified time of the file to the given values. If the\n\
1442second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001443
Barry Warsaw53699e91996-12-10 23:23:01 +00001444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001445posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001446{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001447 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001448 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001449 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001450 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001451
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001452/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001453#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001454 struct utimbuf buf;
1455#define ATIME buf.actime
1456#define MTIME buf.modtime
1457#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001458#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001459 time_t buf[2];
1460#define ATIME buf[0]
1461#define MTIME buf[1]
1462#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001463#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001464
Barry Warsaw3cef8562000-05-01 16:17:24 +00001465 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001466 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001467 if (arg == Py_None) {
1468 /* optional time values not given */
1469 Py_BEGIN_ALLOW_THREADS
1470 res = utime(path, NULL);
1471 Py_END_ALLOW_THREADS
1472 }
1473 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1474 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001475 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001476 return NULL;
1477 }
1478 else {
1479 ATIME = atime;
1480 MTIME = mtime;
1481 Py_BEGIN_ALLOW_THREADS
1482 res = utime(path, UTIME_ARG);
1483 Py_END_ALLOW_THREADS
1484 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001485 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001486 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001487 Py_INCREF(Py_None);
1488 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001489#undef UTIME_ARG
1490#undef ATIME
1491#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001492}
1493
Guido van Rossum85e3b011991-06-03 12:42:10 +00001494
Guido van Rossum3b066191991-06-04 19:40:25 +00001495/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001496
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001497static char posix__exit__doc__[] =
1498"_exit(status)\n\
1499Exit to the system with specified status, without normal exit processing.";
1500
Barry Warsaw53699e91996-12-10 23:23:01 +00001501static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001502posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001503{
1504 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001505 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001506 return NULL;
1507 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001508 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001509}
1510
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001511
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001512#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001513static char posix_execv__doc__[] =
1514"execv(path, args)\n\
1515Execute an executable path with arguments, replacing current process.\n\
1516\n\
1517 path: path of executable file\n\
1518 args: tuple or list of strings";
1519
Barry Warsaw53699e91996-12-10 23:23:01 +00001520static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001521posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001522{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001523 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001524 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001525 char **argvlist;
1526 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001527 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001528
Guido van Rossum89b33251993-10-22 14:26:06 +00001529 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001530 argv is a list or tuple of strings. */
1531
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001532 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001533 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001534 if (PyList_Check(argv)) {
1535 argc = PyList_Size(argv);
1536 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001537 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001538 else if (PyTuple_Check(argv)) {
1539 argc = PyTuple_Size(argv);
1540 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001541 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001542 else {
Fred Drake661ea262000-10-24 19:57:45 +00001543 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001544 return NULL;
1545 }
1546
1547 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001548 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001549 return NULL;
1550 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001551
Barry Warsaw53699e91996-12-10 23:23:01 +00001552 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001553 if (argvlist == NULL)
1554 return NULL;
1555 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001556 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1557 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001558 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001559 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001560 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001561
Guido van Rossum85e3b011991-06-03 12:42:10 +00001562 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001563 }
1564 argvlist[argc] = NULL;
1565
Guido van Rossumb6775db1994-08-01 11:34:53 +00001566#ifdef BAD_EXEC_PROTOTYPES
1567 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001568#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001569 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001570#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001571
Guido van Rossum85e3b011991-06-03 12:42:10 +00001572 /* If we get here it's definitely an error */
1573
Barry Warsaw53699e91996-12-10 23:23:01 +00001574 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001575 return posix_error();
1576}
1577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001578
1579static char posix_execve__doc__[] =
1580"execve(path, args, env)\n\
1581Execute a path with arguments and environment, replacing current process.\n\
1582\n\
1583 path: path of executable file\n\
1584 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001585 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001586
Barry Warsaw53699e91996-12-10 23:23:01 +00001587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001588posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001589{
1590 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001591 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001592 char **argvlist;
1593 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001594 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001595 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001596 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001597
1598 /* execve has three arguments: (path, argv, env), where
1599 argv is a list or tuple of strings and env is a dictionary
1600 like posix.environ. */
1601
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001602 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001603 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001604 if (PyList_Check(argv)) {
1605 argc = PyList_Size(argv);
1606 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001607 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001608 else if (PyTuple_Check(argv)) {
1609 argc = PyTuple_Size(argv);
1610 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001611 }
1612 else {
Fred Drake661ea262000-10-24 19:57:45 +00001613 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001614 return NULL;
1615 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001616 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001617 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001618 return NULL;
1619 }
1620
Guido van Rossum50422b42000-04-26 20:34:28 +00001621 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001622 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001623 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001624 return NULL;
1625 }
1626
Barry Warsaw53699e91996-12-10 23:23:01 +00001627 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001628 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001629 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001630 return NULL;
1631 }
1632 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001633 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001634 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001635 &argvlist[i]))
1636 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001637 goto fail_1;
1638 }
1639 }
1640 argvlist[argc] = NULL;
1641
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001642 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001643 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001644 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001645 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001646 goto fail_1;
1647 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001648 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001649 keys = PyMapping_Keys(env);
1650 vals = PyMapping_Values(env);
1651 if (!keys || !vals)
1652 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001653
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001654 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001655 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001656 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001657
1658 key = PyList_GetItem(keys, pos);
1659 val = PyList_GetItem(vals, pos);
1660 if (!key || !val)
1661 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001662
Fred Drake661ea262000-10-24 19:57:45 +00001663 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1664 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001665 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001666 goto fail_2;
1667 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001668
1669#if defined(PYOS_OS2)
1670 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1671 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1672#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001673 len = PyString_Size(key) + PyString_Size(val) + 2;
1674 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001675 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001676 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001677 goto fail_2;
1678 }
Tim Petersc8996f52001-12-03 20:41:00 +00001679 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001680 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001681#if defined(PYOS_OS2)
1682 }
1683#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001684 }
1685 envlist[envc] = 0;
1686
Guido van Rossumb6775db1994-08-01 11:34:53 +00001687
1688#ifdef BAD_EXEC_PROTOTYPES
1689 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001690#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001691 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001692#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001693
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001694 /* If we get here it's definitely an error */
1695
1696 (void) posix_error();
1697
1698 fail_2:
1699 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001700 PyMem_DEL(envlist[envc]);
1701 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001702 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001703 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001704 Py_XDECREF(vals);
1705 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001706 return NULL;
1707}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001708#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001709
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001710
Guido van Rossuma1065681999-01-25 23:20:23 +00001711#ifdef HAVE_SPAWNV
1712static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001713"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001714Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001715\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001716 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001717 path: path of executable file\n\
1718 args: tuple or list of strings";
1719
1720static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001721posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001722{
1723 char *path;
1724 PyObject *argv;
1725 char **argvlist;
1726 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001727 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001728 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001729
1730 /* spawnv has three arguments: (mode, path, argv), where
1731 argv is a list or tuple of strings. */
1732
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001733 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001734 return NULL;
1735 if (PyList_Check(argv)) {
1736 argc = PyList_Size(argv);
1737 getitem = PyList_GetItem;
1738 }
1739 else if (PyTuple_Check(argv)) {
1740 argc = PyTuple_Size(argv);
1741 getitem = PyTuple_GetItem;
1742 }
1743 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001744 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001745 return NULL;
1746 }
1747
1748 argvlist = PyMem_NEW(char *, argc+1);
1749 if (argvlist == NULL)
1750 return NULL;
1751 for (i = 0; i < argc; i++) {
1752 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1753 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001754 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001755 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001756 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001757 }
1758 }
1759 argvlist[argc] = NULL;
1760
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001761#if defined(PYOS_OS2) && defined(PYCC_GCC)
1762 Py_BEGIN_ALLOW_THREADS
1763 spawnval = spawnv(mode, path, argvlist);
1764 Py_END_ALLOW_THREADS
1765#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001766 if (mode == _OLD_P_OVERLAY)
1767 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001768
Tim Peters25059d32001-12-07 20:35:43 +00001769 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001770 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001771 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001772#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001773
Guido van Rossuma1065681999-01-25 23:20:23 +00001774 PyMem_DEL(argvlist);
1775
Fred Drake699f3522000-06-29 21:12:41 +00001776 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001777 return posix_error();
1778 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001779#if SIZEOF_LONG == SIZEOF_VOID_P
1780 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001781#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001782 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001783#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001784}
1785
1786
1787static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001788"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001789Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001790\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001791 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001792 path: path of executable file\n\
1793 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001794 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001795
1796static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001797posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001798{
1799 char *path;
1800 PyObject *argv, *env;
1801 char **argvlist;
1802 char **envlist;
1803 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1804 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001805 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001806 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001807
1808 /* spawnve has four arguments: (mode, path, argv, env), where
1809 argv is a list or tuple of strings and env is a dictionary
1810 like posix.environ. */
1811
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001812 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001813 return NULL;
1814 if (PyList_Check(argv)) {
1815 argc = PyList_Size(argv);
1816 getitem = PyList_GetItem;
1817 }
1818 else if (PyTuple_Check(argv)) {
1819 argc = PyTuple_Size(argv);
1820 getitem = PyTuple_GetItem;
1821 }
1822 else {
Fred Drake661ea262000-10-24 19:57:45 +00001823 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001824 return NULL;
1825 }
1826 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001827 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001828 return NULL;
1829 }
1830
1831 argvlist = PyMem_NEW(char *, argc+1);
1832 if (argvlist == NULL) {
1833 PyErr_NoMemory();
1834 return NULL;
1835 }
1836 for (i = 0; i < argc; i++) {
1837 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001838 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001839 &argvlist[i]))
1840 {
1841 goto fail_1;
1842 }
1843 }
1844 argvlist[argc] = NULL;
1845
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001846 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001847 envlist = PyMem_NEW(char *, i + 1);
1848 if (envlist == NULL) {
1849 PyErr_NoMemory();
1850 goto fail_1;
1851 }
1852 envc = 0;
1853 keys = PyMapping_Keys(env);
1854 vals = PyMapping_Values(env);
1855 if (!keys || !vals)
1856 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001857
Guido van Rossuma1065681999-01-25 23:20:23 +00001858 for (pos = 0; pos < i; pos++) {
1859 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001860 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001861
1862 key = PyList_GetItem(keys, pos);
1863 val = PyList_GetItem(vals, pos);
1864 if (!key || !val)
1865 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001866
Fred Drake661ea262000-10-24 19:57:45 +00001867 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1868 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001869 {
1870 goto fail_2;
1871 }
Tim Petersc8996f52001-12-03 20:41:00 +00001872 len = PyString_Size(key) + PyString_Size(val) + 2;
1873 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001874 if (p == NULL) {
1875 PyErr_NoMemory();
1876 goto fail_2;
1877 }
Tim Petersc8996f52001-12-03 20:41:00 +00001878 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001879 envlist[envc++] = p;
1880 }
1881 envlist[envc] = 0;
1882
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001883#if defined(PYOS_OS2) && defined(PYCC_GCC)
1884 Py_BEGIN_ALLOW_THREADS
1885 spawnval = spawnve(mode, path, argvlist, envlist);
1886 Py_END_ALLOW_THREADS
1887#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001888 if (mode == _OLD_P_OVERLAY)
1889 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001890
1891 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001892 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001893 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001894#endif
Tim Peters25059d32001-12-07 20:35:43 +00001895
Fred Drake699f3522000-06-29 21:12:41 +00001896 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001897 (void) posix_error();
1898 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001899#if SIZEOF_LONG == SIZEOF_VOID_P
1900 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001901#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001902 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001903#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001904
1905 fail_2:
1906 while (--envc >= 0)
1907 PyMem_DEL(envlist[envc]);
1908 PyMem_DEL(envlist);
1909 fail_1:
1910 PyMem_DEL(argvlist);
1911 Py_XDECREF(vals);
1912 Py_XDECREF(keys);
1913 return res;
1914}
1915#endif /* HAVE_SPAWNV */
1916
1917
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001918#ifdef HAVE_FORK1
1919static char posix_fork1__doc__[] =
1920"fork1() -> pid\n\
1921Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1922\n\
1923Return 0 to child process and PID of child to parent process.";
1924
1925static PyObject *
1926posix_fork1(self, args)
1927 PyObject *self;
1928 PyObject *args;
1929{
1930 int pid;
1931 if (!PyArg_ParseTuple(args, ":fork1"))
1932 return NULL;
1933 pid = fork1();
1934 if (pid == -1)
1935 return posix_error();
1936 PyOS_AfterFork();
1937 return PyInt_FromLong((long)pid);
1938}
1939#endif
1940
1941
Guido van Rossumad0ee831995-03-01 10:34:45 +00001942#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001943static char posix_fork__doc__[] =
1944"fork() -> pid\n\
1945Fork a child process.\n\
1946\n\
1947Return 0 to child process and PID of child to parent process.";
1948
Barry Warsaw53699e91996-12-10 23:23:01 +00001949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001950posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001951{
1952 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001953 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001954 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001955 pid = fork();
1956 if (pid == -1)
1957 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001958 if (pid == 0)
1959 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001960 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001961}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001962#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001963
Fred Drake8cef4cf2000-06-28 16:40:38 +00001964#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1965#ifdef HAVE_PTY_H
1966#include <pty.h>
1967#else
1968#ifdef HAVE_LIBUTIL_H
1969#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001970#endif /* HAVE_LIBUTIL_H */
1971#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001972#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001973
Thomas Wouters70c21a12000-07-14 14:28:33 +00001974#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001975static char posix_openpty__doc__[] =
1976"openpty() -> (master_fd, slave_fd)\n\
1977Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1978
1979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001980posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001981{
1982 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001983#ifndef HAVE_OPENPTY
1984 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001985#endif
1986
Fred Drake8cef4cf2000-06-28 16:40:38 +00001987 if (!PyArg_ParseTuple(args, ":openpty"))
1988 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001989
1990#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001991 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1992 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001993#else
1994 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1995 if (slave_name == NULL)
1996 return posix_error();
1997
1998 slave_fd = open(slave_name, O_RDWR);
1999 if (slave_fd < 0)
2000 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002001#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002002
Fred Drake8cef4cf2000-06-28 16:40:38 +00002003 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002004
Fred Drake8cef4cf2000-06-28 16:40:38 +00002005}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002006#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002007
2008#ifdef HAVE_FORKPTY
2009static char posix_forkpty__doc__[] =
2010"forkpty() -> (pid, master_fd)\n\
2011Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2012Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
2013To both, return fd of newly opened pseudo-terminal.\n";
2014
2015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002016posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002017{
2018 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002019
Fred Drake8cef4cf2000-06-28 16:40:38 +00002020 if (!PyArg_ParseTuple(args, ":forkpty"))
2021 return NULL;
2022 pid = forkpty(&master_fd, NULL, NULL, NULL);
2023 if (pid == -1)
2024 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002025 if (pid == 0)
2026 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002027 return Py_BuildValue("(ii)", pid, master_fd);
2028}
2029#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002030
Guido van Rossumad0ee831995-03-01 10:34:45 +00002031#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002032static char posix_getegid__doc__[] =
2033"getegid() -> egid\n\
2034Return the current process's effective group id.";
2035
Barry Warsaw53699e91996-12-10 23:23:01 +00002036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002037posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002038{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002039 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002040 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002041 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002042}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002043#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002044
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002045
Guido van Rossumad0ee831995-03-01 10:34:45 +00002046#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002047static char posix_geteuid__doc__[] =
2048"geteuid() -> euid\n\
2049Return the current process's effective user id.";
2050
Barry Warsaw53699e91996-12-10 23:23:01 +00002051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002052posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002053{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002054 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002055 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002056 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002057}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002058#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002060
Guido van Rossumad0ee831995-03-01 10:34:45 +00002061#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002062static char posix_getgid__doc__[] =
2063"getgid() -> gid\n\
2064Return the current process's group id.";
2065
Barry Warsaw53699e91996-12-10 23:23:01 +00002066static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002067posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002068{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002069 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002070 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002071 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002072}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002073#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
2076static char posix_getpid__doc__[] =
2077"getpid() -> pid\n\
2078Return the current process id";
2079
Barry Warsaw53699e91996-12-10 23:23:01 +00002080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002081posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002082{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002083 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002084 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002085 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002086}
2087
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002088
Fred Drakec9680921999-12-13 16:37:25 +00002089#ifdef HAVE_GETGROUPS
2090static char posix_getgroups__doc__[] = "\
2091getgroups() -> list of group IDs\n\
2092Return list of supplemental group IDs for the process.";
2093
2094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002095posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002096{
2097 PyObject *result = NULL;
2098
2099 if (PyArg_ParseTuple(args, ":getgroups")) {
2100#ifdef NGROUPS_MAX
2101#define MAX_GROUPS NGROUPS_MAX
2102#else
2103 /* defined to be 16 on Solaris7, so this should be a small number */
2104#define MAX_GROUPS 64
2105#endif
2106 gid_t grouplist[MAX_GROUPS];
2107 int n;
2108
2109 n = getgroups(MAX_GROUPS, grouplist);
2110 if (n < 0)
2111 posix_error();
2112 else {
2113 result = PyList_New(n);
2114 if (result != NULL) {
2115 PyObject *o;
2116 int i;
2117 for (i = 0; i < n; ++i) {
2118 o = PyInt_FromLong((long)grouplist[i]);
2119 if (o == NULL) {
2120 Py_DECREF(result);
2121 result = NULL;
2122 break;
2123 }
2124 PyList_SET_ITEM(result, i, o);
2125 }
2126 }
2127 }
2128 }
2129 return result;
2130}
2131#endif
2132
Guido van Rossumb6775db1994-08-01 11:34:53 +00002133#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002134static char posix_getpgrp__doc__[] =
2135"getpgrp() -> pgrp\n\
2136Return the current process group id.";
2137
Barry Warsaw53699e91996-12-10 23:23:01 +00002138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002139posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002140{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002141 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002142 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002143#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002144 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002145#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002146 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002147#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002148}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002149#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002150
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002151
Guido van Rossumb6775db1994-08-01 11:34:53 +00002152#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002153static char posix_setpgrp__doc__[] =
2154"setpgrp() -> None\n\
2155Make this process a session leader.";
2156
Barry Warsaw53699e91996-12-10 23:23:01 +00002157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002158posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002159{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002160 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002161 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002162#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002163 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002164#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002165 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002166#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002167 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002168 Py_INCREF(Py_None);
2169 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002170}
2171
Guido van Rossumb6775db1994-08-01 11:34:53 +00002172#endif /* HAVE_SETPGRP */
2173
Guido van Rossumad0ee831995-03-01 10:34:45 +00002174#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002175static char posix_getppid__doc__[] =
2176"getppid() -> ppid\n\
2177Return the parent's process id.";
2178
Barry Warsaw53699e91996-12-10 23:23:01 +00002179static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002180posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002181{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002182 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002183 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002184 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002185}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002186#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002188
Fred Drake12c6e2d1999-12-14 21:25:03 +00002189#ifdef HAVE_GETLOGIN
2190static char posix_getlogin__doc__[] = "\
2191getlogin() -> string\n\
2192Return the actual login name.";
2193
2194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002195posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002196{
2197 PyObject *result = NULL;
2198
2199 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002200 char *name;
2201 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002202
Fred Drakea30680b2000-12-06 21:24:28 +00002203 errno = 0;
2204 name = getlogin();
2205 if (name == NULL) {
2206 if (errno)
2207 posix_error();
2208 else
2209 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002210 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002211 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002212 else
2213 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002214 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002215 }
2216 return result;
2217}
2218#endif
2219
Guido van Rossumad0ee831995-03-01 10:34:45 +00002220#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002221static char posix_getuid__doc__[] =
2222"getuid() -> uid\n\
2223Return the current process's user id.";
2224
Barry Warsaw53699e91996-12-10 23:23:01 +00002225static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002226posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002227{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002228 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002229 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002230 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002231}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002232#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002234
Guido van Rossumad0ee831995-03-01 10:34:45 +00002235#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002236static char posix_kill__doc__[] =
2237"kill(pid, sig) -> None\n\
2238Kill a process with a signal.";
2239
Barry Warsaw53699e91996-12-10 23:23:01 +00002240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002241posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002242{
2243 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002244 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002245 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002246#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002247 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2248 APIRET rc;
2249 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002250 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002251
2252 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2253 APIRET rc;
2254 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002255 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002256
2257 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002258 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002259#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002260 if (kill(pid, sig) == -1)
2261 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002262#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002263 Py_INCREF(Py_None);
2264 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002265}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002266#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002267
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002268#ifdef HAVE_KILLPG
2269static char posix_killpg__doc__[] =
2270"killpg(pgid, sig) -> None\n\
2271Kill a process group with a signal.";
2272
2273static PyObject *
2274posix_killpg(PyObject *self, PyObject *args)
2275{
2276 int pgid, sig;
2277 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2278 return NULL;
2279 if (killpg(pgid, sig) == -1)
2280 return posix_error();
2281 Py_INCREF(Py_None);
2282 return Py_None;
2283}
2284#endif
2285
Guido van Rossumc0125471996-06-28 18:55:32 +00002286#ifdef HAVE_PLOCK
2287
2288#ifdef HAVE_SYS_LOCK_H
2289#include <sys/lock.h>
2290#endif
2291
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002292static char posix_plock__doc__[] =
2293"plock(op) -> None\n\
2294Lock program segments into memory.";
2295
Barry Warsaw53699e91996-12-10 23:23:01 +00002296static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002297posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002298{
2299 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002300 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002301 return NULL;
2302 if (plock(op) == -1)
2303 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002304 Py_INCREF(Py_None);
2305 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002306}
2307#endif
2308
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002309
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002310#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002311static char posix_popen__doc__[] =
2312"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2313Open a pipe to/from a command returning a file object.";
2314
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002315#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002316#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002317static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002318async_system(const char *command)
2319{
2320 char *p, errormsg[256], args[1024];
2321 RESULTCODES rcodes;
2322 APIRET rc;
2323 char *shell = getenv("COMSPEC");
2324 if (!shell)
2325 shell = "cmd";
2326
2327 strcpy(args, shell);
2328 p = &args[ strlen(args)+1 ];
2329 strcpy(p, "/c ");
2330 strcat(p, command);
2331 p += strlen(p) + 1;
2332 *p = '\0';
2333
2334 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002335 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002336 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002337 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002338 &rcodes, shell);
2339 return rc;
2340}
2341
Guido van Rossumd48f2521997-12-05 22:19:34 +00002342static FILE *
2343popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002344{
2345 HFILE rhan, whan;
2346 FILE *retfd = NULL;
2347 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2348
Guido van Rossumd48f2521997-12-05 22:19:34 +00002349 if (rc != NO_ERROR) {
2350 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002351 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002352 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002353
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002354 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2355 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002356
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002357 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2358 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002359
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002360 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2361 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002362
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002363 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002364 }
2365
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002366 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2367 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002368
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002369 if (rc == NO_ERROR)
2370 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2371
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002372 close(oldfd); /* And Close Saved STDOUT Handle */
2373 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002374
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002375 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2376 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002377
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002378 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2379 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002380
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002381 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2382 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002383
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002384 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002385 }
2386
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002387 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2388 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002389
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002390 if (rc == NO_ERROR)
2391 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2392
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002393 close(oldfd); /* And Close Saved STDIN Handle */
2394 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002395
Guido van Rossumd48f2521997-12-05 22:19:34 +00002396 } else {
2397 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002398 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002399 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002400}
2401
2402static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002403posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002404{
2405 char *name;
2406 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002407 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002408 FILE *fp;
2409 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002410 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002411 return NULL;
2412 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002413 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002414 Py_END_ALLOW_THREADS
2415 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002416 return os2_error(err);
2417
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002418 f = PyFile_FromFile(fp, name, mode, fclose);
2419 if (f != NULL)
2420 PyFile_SetBufSize(f, bufsize);
2421 return f;
2422}
2423
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002424#elif defined(PYCC_GCC)
2425
2426/* standard posix version of popen() support */
2427static PyObject *
2428posix_popen(PyObject *self, PyObject *args)
2429{
2430 char *name;
2431 char *mode = "r";
2432 int bufsize = -1;
2433 FILE *fp;
2434 PyObject *f;
2435 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2436 return NULL;
2437 Py_BEGIN_ALLOW_THREADS
2438 fp = popen(name, mode);
2439 Py_END_ALLOW_THREADS
2440 if (fp == NULL)
2441 return posix_error();
2442 f = PyFile_FromFile(fp, name, mode, pclose);
2443 if (f != NULL)
2444 PyFile_SetBufSize(f, bufsize);
2445 return f;
2446}
2447
2448/* fork() under OS/2 has lots'o'warts
2449 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2450 * most of this code is a ripoff of the win32 code, but using the
2451 * capabilities of EMX's C library routines
2452 */
2453
2454/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2455#define POPEN_1 1
2456#define POPEN_2 2
2457#define POPEN_3 3
2458#define POPEN_4 4
2459
2460static PyObject *_PyPopen(char *, int, int, int);
2461static int _PyPclose(FILE *file);
2462
2463/*
2464 * Internal dictionary mapping popen* file pointers to process handles,
2465 * for use when retrieving the process exit code. See _PyPclose() below
2466 * for more information on this dictionary's use.
2467 */
2468static PyObject *_PyPopenProcs = NULL;
2469
2470/* os2emx version of popen2()
2471 *
2472 * The result of this function is a pipe (file) connected to the
2473 * process's stdin, and a pipe connected to the process's stdout.
2474 */
2475
2476static PyObject *
2477os2emx_popen2(PyObject *self, PyObject *args)
2478{
2479 PyObject *f;
2480 int tm=0;
2481
2482 char *cmdstring;
2483 char *mode = "t";
2484 int bufsize = -1;
2485 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2486 return NULL;
2487
2488 if (*mode == 't')
2489 tm = O_TEXT;
2490 else if (*mode != 'b') {
2491 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2492 return NULL;
2493 } else
2494 tm = O_BINARY;
2495
2496 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2497
2498 return f;
2499}
2500
2501/*
2502 * Variation on os2emx.popen2
2503 *
2504 * The result of this function is 3 pipes - the process's stdin,
2505 * stdout and stderr
2506 */
2507
2508static PyObject *
2509os2emx_popen3(PyObject *self, PyObject *args)
2510{
2511 PyObject *f;
2512 int tm = 0;
2513
2514 char *cmdstring;
2515 char *mode = "t";
2516 int bufsize = -1;
2517 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2518 return NULL;
2519
2520 if (*mode == 't')
2521 tm = O_TEXT;
2522 else if (*mode != 'b') {
2523 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2524 return NULL;
2525 } else
2526 tm = O_BINARY;
2527
2528 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2529
2530 return f;
2531}
2532
2533/*
2534 * Variation on os2emx.popen2
2535 *
2536 * The result of this function is 2 pipes - the processes stdin,
2537 * and stdout+stderr combined as a single pipe.
2538 */
2539
2540static PyObject *
2541os2emx_popen4(PyObject *self, PyObject *args)
2542{
2543 PyObject *f;
2544 int tm = 0;
2545
2546 char *cmdstring;
2547 char *mode = "t";
2548 int bufsize = -1;
2549 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2550 return NULL;
2551
2552 if (*mode == 't')
2553 tm = O_TEXT;
2554 else if (*mode != 'b') {
2555 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2556 return NULL;
2557 } else
2558 tm = O_BINARY;
2559
2560 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2561
2562 return f;
2563}
2564
2565/* a couple of structures for convenient handling of multiple
2566 * file handles and pipes
2567 */
2568struct file_ref
2569{
2570 int handle;
2571 int flags;
2572};
2573
2574struct pipe_ref
2575{
2576 int rd;
2577 int wr;
2578};
2579
2580/* The following code is derived from the win32 code */
2581
2582static PyObject *
2583_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2584{
2585 struct file_ref stdio[3];
2586 struct pipe_ref p_fd[3];
2587 FILE *p_s[3];
2588 int file_count, i, pipe_err, pipe_pid;
2589 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2590 PyObject *f, *p_f[3];
2591
2592 /* file modes for subsequent fdopen's on pipe handles */
2593 if (mode == O_TEXT)
2594 {
2595 rd_mode = "rt";
2596 wr_mode = "wt";
2597 }
2598 else
2599 {
2600 rd_mode = "rb";
2601 wr_mode = "wb";
2602 }
2603
2604 /* prepare shell references */
2605 if ((shell = getenv("EMXSHELL")) == NULL)
2606 if ((shell = getenv("COMSPEC")) == NULL)
2607 {
2608 errno = ENOENT;
2609 return posix_error();
2610 }
2611
2612 sh_name = _getname(shell);
2613 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2614 opt = "/c";
2615 else
2616 opt = "-c";
2617
2618 /* save current stdio fds + their flags, and set not inheritable */
2619 i = pipe_err = 0;
2620 while (pipe_err >= 0 && i < 3)
2621 {
2622 pipe_err = stdio[i].handle = dup(i);
2623 stdio[i].flags = fcntl(i, F_GETFD, 0);
2624 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2625 i++;
2626 }
2627 if (pipe_err < 0)
2628 {
2629 /* didn't get them all saved - clean up and bail out */
2630 int saved_err = errno;
2631 while (i-- > 0)
2632 {
2633 close(stdio[i].handle);
2634 }
2635 errno = saved_err;
2636 return posix_error();
2637 }
2638
2639 /* create pipe ends */
2640 file_count = 2;
2641 if (n == POPEN_3)
2642 file_count = 3;
2643 i = pipe_err = 0;
2644 while ((pipe_err == 0) && (i < file_count))
2645 pipe_err = pipe((int *)&p_fd[i++]);
2646 if (pipe_err < 0)
2647 {
2648 /* didn't get them all made - clean up and bail out */
2649 while (i-- > 0)
2650 {
2651 close(p_fd[i].wr);
2652 close(p_fd[i].rd);
2653 }
2654 errno = EPIPE;
2655 return posix_error();
2656 }
2657
2658 /* change the actual standard IO streams over temporarily,
2659 * making the retained pipe ends non-inheritable
2660 */
2661 pipe_err = 0;
2662
2663 /* - stdin */
2664 if (dup2(p_fd[0].rd, 0) == 0)
2665 {
2666 close(p_fd[0].rd);
2667 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2668 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2669 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2670 {
2671 close(p_fd[0].wr);
2672 pipe_err = -1;
2673 }
2674 }
2675 else
2676 {
2677 pipe_err = -1;
2678 }
2679
2680 /* - stdout */
2681 if (pipe_err == 0)
2682 {
2683 if (dup2(p_fd[1].wr, 1) == 1)
2684 {
2685 close(p_fd[1].wr);
2686 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2687 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2688 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2689 {
2690 close(p_fd[1].rd);
2691 pipe_err = -1;
2692 }
2693 }
2694 else
2695 {
2696 pipe_err = -1;
2697 }
2698 }
2699
2700 /* - stderr, as required */
2701 if (pipe_err == 0)
2702 switch (n)
2703 {
2704 case POPEN_3:
2705 {
2706 if (dup2(p_fd[2].wr, 2) == 2)
2707 {
2708 close(p_fd[2].wr);
2709 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2710 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2711 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2712 {
2713 close(p_fd[2].rd);
2714 pipe_err = -1;
2715 }
2716 }
2717 else
2718 {
2719 pipe_err = -1;
2720 }
2721 break;
2722 }
2723
2724 case POPEN_4:
2725 {
2726 if (dup2(1, 2) != 2)
2727 {
2728 pipe_err = -1;
2729 }
2730 break;
2731 }
2732 }
2733
2734 /* spawn the child process */
2735 if (pipe_err == 0)
2736 {
2737 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2738 if (pipe_pid == -1)
2739 {
2740 pipe_err = -1;
2741 }
2742 else
2743 {
2744 /* save the PID into the FILE structure
2745 * NOTE: this implementation doesn't actually
2746 * take advantage of this, but do it for
2747 * completeness - AIM Apr01
2748 */
2749 for (i = 0; i < file_count; i++)
2750 p_s[i]->_pid = pipe_pid;
2751 }
2752 }
2753
2754 /* reset standard IO to normal */
2755 for (i = 0; i < 3; i++)
2756 {
2757 dup2(stdio[i].handle, i);
2758 fcntl(i, F_SETFD, stdio[i].flags);
2759 close(stdio[i].handle);
2760 }
2761
2762 /* if any remnant problems, clean up and bail out */
2763 if (pipe_err < 0)
2764 {
2765 for (i = 0; i < 3; i++)
2766 {
2767 close(p_fd[i].rd);
2768 close(p_fd[i].wr);
2769 }
2770 errno = EPIPE;
2771 return posix_error_with_filename(cmdstring);
2772 }
2773
2774 /* build tuple of file objects to return */
2775 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2776 PyFile_SetBufSize(p_f[0], bufsize);
2777 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2778 PyFile_SetBufSize(p_f[1], bufsize);
2779 if (n == POPEN_3)
2780 {
2781 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2782 PyFile_SetBufSize(p_f[0], bufsize);
2783 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2784 }
2785 else
2786 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2787
2788 /*
2789 * Insert the files we've created into the process dictionary
2790 * all referencing the list with the process handle and the
2791 * initial number of files (see description below in _PyPclose).
2792 * Since if _PyPclose later tried to wait on a process when all
2793 * handles weren't closed, it could create a deadlock with the
2794 * child, we spend some energy here to try to ensure that we
2795 * either insert all file handles into the dictionary or none
2796 * at all. It's a little clumsy with the various popen modes
2797 * and variable number of files involved.
2798 */
2799 if (!_PyPopenProcs)
2800 {
2801 _PyPopenProcs = PyDict_New();
2802 }
2803
2804 if (_PyPopenProcs)
2805 {
2806 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2807 int ins_rc[3];
2808
2809 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2810 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2811
2812 procObj = PyList_New(2);
2813 pidObj = PyInt_FromLong((long) pipe_pid);
2814 intObj = PyInt_FromLong((long) file_count);
2815
2816 if (procObj && pidObj && intObj)
2817 {
2818 PyList_SetItem(procObj, 0, pidObj);
2819 PyList_SetItem(procObj, 1, intObj);
2820
2821 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2822 if (fileObj[0])
2823 {
2824 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2825 fileObj[0],
2826 procObj);
2827 }
2828 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2829 if (fileObj[1])
2830 {
2831 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2832 fileObj[1],
2833 procObj);
2834 }
2835 if (file_count >= 3)
2836 {
2837 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2838 if (fileObj[2])
2839 {
2840 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2841 fileObj[2],
2842 procObj);
2843 }
2844 }
2845
2846 if (ins_rc[0] < 0 || !fileObj[0] ||
2847 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2848 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2849 {
2850 /* Something failed - remove any dictionary
2851 * entries that did make it.
2852 */
2853 if (!ins_rc[0] && fileObj[0])
2854 {
2855 PyDict_DelItem(_PyPopenProcs,
2856 fileObj[0]);
2857 }
2858 if (!ins_rc[1] && fileObj[1])
2859 {
2860 PyDict_DelItem(_PyPopenProcs,
2861 fileObj[1]);
2862 }
2863 if (!ins_rc[2] && fileObj[2])
2864 {
2865 PyDict_DelItem(_PyPopenProcs,
2866 fileObj[2]);
2867 }
2868 }
2869 }
2870
2871 /*
2872 * Clean up our localized references for the dictionary keys
2873 * and value since PyDict_SetItem will Py_INCREF any copies
2874 * that got placed in the dictionary.
2875 */
2876 Py_XDECREF(procObj);
2877 Py_XDECREF(fileObj[0]);
2878 Py_XDECREF(fileObj[1]);
2879 Py_XDECREF(fileObj[2]);
2880 }
2881
2882 /* Child is launched. */
2883 return f;
2884}
2885
2886/*
2887 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2888 * exit code for the child process and return as a result of the close.
2889 *
2890 * This function uses the _PyPopenProcs dictionary in order to map the
2891 * input file pointer to information about the process that was
2892 * originally created by the popen* call that created the file pointer.
2893 * The dictionary uses the file pointer as a key (with one entry
2894 * inserted for each file returned by the original popen* call) and a
2895 * single list object as the value for all files from a single call.
2896 * The list object contains the Win32 process handle at [0], and a file
2897 * count at [1], which is initialized to the total number of file
2898 * handles using that list.
2899 *
2900 * This function closes whichever handle it is passed, and decrements
2901 * the file count in the dictionary for the process handle pointed to
2902 * by this file. On the last close (when the file count reaches zero),
2903 * this function will wait for the child process and then return its
2904 * exit code as the result of the close() operation. This permits the
2905 * files to be closed in any order - it is always the close() of the
2906 * final handle that will return the exit code.
2907 */
2908
2909 /* RED_FLAG 31-Aug-2000 Tim
2910 * This is always called (today!) between a pair of
2911 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2912 * macros. So the thread running this has no valid thread state, as
2913 * far as Python is concerned. However, this calls some Python API
2914 * functions that cannot be called safely without a valid thread
2915 * state, in particular PyDict_GetItem.
2916 * As a temporary hack (although it may last for years ...), we
2917 * *rely* on not having a valid thread state in this function, in
2918 * order to create our own "from scratch".
2919 * This will deadlock if _PyPclose is ever called by a thread
2920 * holding the global lock.
2921 * (The OS/2 EMX thread support appears to cover the case where the
2922 * lock is already held - AIM Apr01)
2923 */
2924
2925static int _PyPclose(FILE *file)
2926{
2927 int result;
2928 int exit_code;
2929 int pipe_pid;
2930 PyObject *procObj, *pidObj, *intObj, *fileObj;
2931 int file_count;
2932#ifdef WITH_THREAD
2933 PyInterpreterState* pInterpreterState;
2934 PyThreadState* pThreadState;
2935#endif
2936
2937 /* Close the file handle first, to ensure it can't block the
2938 * child from exiting if it's the last handle.
2939 */
2940 result = fclose(file);
2941
2942#ifdef WITH_THREAD
2943 /* Bootstrap a valid thread state into existence. */
2944 pInterpreterState = PyInterpreterState_New();
2945 if (!pInterpreterState) {
2946 /* Well, we're hosed now! We don't have a thread
2947 * state, so can't call a nice error routine, or raise
2948 * an exception. Just die.
2949 */
2950 Py_FatalError("unable to allocate interpreter state "
2951 "when closing popen object.");
2952 return -1; /* unreachable */
2953 }
2954 pThreadState = PyThreadState_New(pInterpreterState);
2955 if (!pThreadState) {
2956 Py_FatalError("unable to allocate thread state "
2957 "when closing popen object.");
2958 return -1; /* unreachable */
2959 }
2960 /* Grab the global lock. Note that this will deadlock if the
2961 * current thread already has the lock! (see RED_FLAG comments
2962 * before this function)
2963 */
2964 PyEval_RestoreThread(pThreadState);
2965#endif
2966
2967 if (_PyPopenProcs)
2968 {
2969 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2970 (procObj = PyDict_GetItem(_PyPopenProcs,
2971 fileObj)) != NULL &&
2972 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2973 (intObj = PyList_GetItem(procObj,1)) != NULL)
2974 {
2975 pipe_pid = (int) PyInt_AsLong(pidObj);
2976 file_count = (int) PyInt_AsLong(intObj);
2977
2978 if (file_count > 1)
2979 {
2980 /* Still other files referencing process */
2981 file_count--;
2982 PyList_SetItem(procObj,1,
2983 PyInt_FromLong((long) file_count));
2984 }
2985 else
2986 {
2987 /* Last file for this process */
2988 if (result != EOF &&
2989 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2990 {
2991 /* extract exit status */
2992 if (WIFEXITED(exit_code))
2993 {
2994 result = WEXITSTATUS(exit_code);
2995 }
2996 else
2997 {
2998 errno = EPIPE;
2999 result = -1;
3000 }
3001 }
3002 else
3003 {
3004 /* Indicate failure - this will cause the file object
3005 * to raise an I/O error and translate the last
3006 * error code from errno. We do have a problem with
3007 * last errors that overlap the normal errno table,
3008 * but that's a consistent problem with the file object.
3009 */
3010 result = -1;
3011 }
3012 }
3013
3014 /* Remove this file pointer from dictionary */
3015 PyDict_DelItem(_PyPopenProcs, fileObj);
3016
3017 if (PyDict_Size(_PyPopenProcs) == 0)
3018 {
3019 Py_DECREF(_PyPopenProcs);
3020 _PyPopenProcs = NULL;
3021 }
3022
3023 } /* if object retrieval ok */
3024
3025 Py_XDECREF(fileObj);
3026 } /* if _PyPopenProcs */
3027
3028#ifdef WITH_THREAD
3029 /* Tear down the thread & interpreter states.
3030 * Note that interpreter state clear & delete functions automatically
3031 * call the thread clear & delete functions, and indeed insist on
3032 * doing that themselves. The lock must be held during the clear, but
3033 * need not be held during the delete.
3034 */
3035 PyInterpreterState_Clear(pInterpreterState);
3036 PyEval_ReleaseThread(pThreadState);
3037 PyInterpreterState_Delete(pInterpreterState);
3038#endif
3039
3040 return result;
3041}
3042
3043#endif /* PYCC_??? */
3044
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003045#elif defined(MS_WIN32)
3046
3047/*
3048 * Portable 'popen' replacement for Win32.
3049 *
3050 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3051 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003052 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003053 */
3054
3055#include <malloc.h>
3056#include <io.h>
3057#include <fcntl.h>
3058
3059/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3060#define POPEN_1 1
3061#define POPEN_2 2
3062#define POPEN_3 3
3063#define POPEN_4 4
3064
3065static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003066static int _PyPclose(FILE *file);
3067
3068/*
3069 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003070 * for use when retrieving the process exit code. See _PyPclose() below
3071 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003072 */
3073static PyObject *_PyPopenProcs = NULL;
3074
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003075
3076/* popen that works from a GUI.
3077 *
3078 * The result of this function is a pipe (file) connected to the
3079 * processes stdin or stdout, depending on the requested mode.
3080 */
3081
3082static PyObject *
3083posix_popen(PyObject *self, PyObject *args)
3084{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003085 PyObject *f, *s;
3086 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003087
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003088 char *cmdstring;
3089 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003090 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003091 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003092 return NULL;
3093
3094 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003095
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003096 if (*mode == 'r')
3097 tm = _O_RDONLY;
3098 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003099 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003100 return NULL;
3101 } else
3102 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003103
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003104 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003105 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003106 return NULL;
3107 }
3108
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003109 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003110 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003111 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003112 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003113 else
3114 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3115
3116 return f;
3117}
3118
3119/* Variation on win32pipe.popen
3120 *
3121 * The result of this function is a pipe (file) connected to the
3122 * process's stdin, and a pipe connected to the process's stdout.
3123 */
3124
3125static PyObject *
3126win32_popen2(PyObject *self, PyObject *args)
3127{
3128 PyObject *f;
3129 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003130
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003131 char *cmdstring;
3132 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003133 int bufsize = -1;
3134 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003135 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003136
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003137 if (*mode == 't')
3138 tm = _O_TEXT;
3139 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003140 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003141 return NULL;
3142 } else
3143 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003144
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003145 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003146 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003147 return NULL;
3148 }
3149
3150 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003151
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003152 return f;
3153}
3154
3155/*
3156 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003157 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003158 * The result of this function is 3 pipes - the process's stdin,
3159 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003160 */
3161
3162static PyObject *
3163win32_popen3(PyObject *self, PyObject *args)
3164{
3165 PyObject *f;
3166 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003167
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003168 char *cmdstring;
3169 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003170 int bufsize = -1;
3171 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003172 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003173
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003174 if (*mode == 't')
3175 tm = _O_TEXT;
3176 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003177 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003178 return NULL;
3179 } else
3180 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003181
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003182 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003183 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003184 return NULL;
3185 }
3186
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003187 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003188
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003189 return f;
3190}
3191
3192/*
3193 * Variation on win32pipe.popen
3194 *
Tim Peters5aa91602002-01-30 05:46:57 +00003195 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003196 * and stdout+stderr combined as a single pipe.
3197 */
3198
3199static PyObject *
3200win32_popen4(PyObject *self, PyObject *args)
3201{
3202 PyObject *f;
3203 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003204
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003205 char *cmdstring;
3206 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003207 int bufsize = -1;
3208 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003209 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003210
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003211 if (*mode == 't')
3212 tm = _O_TEXT;
3213 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003214 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003215 return NULL;
3216 } else
3217 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003218
3219 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003220 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003221 return NULL;
3222 }
3223
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003224 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003225
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003226 return f;
3227}
3228
Mark Hammond08501372001-01-31 07:30:29 +00003229static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003230_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003231 HANDLE hStdin,
3232 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003233 HANDLE hStderr,
3234 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003235{
3236 PROCESS_INFORMATION piProcInfo;
3237 STARTUPINFO siStartInfo;
3238 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003239 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003240 int i;
3241 int x;
3242
3243 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003244 char *comshell;
3245
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003246 s1 = (char *)_alloca(i);
3247 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3248 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003249
3250 /* Explicitly check if we are using COMMAND.COM. If we are
3251 * then use the w9xpopen hack.
3252 */
3253 comshell = s1 + x;
3254 while (comshell >= s1 && *comshell != '\\')
3255 --comshell;
3256 ++comshell;
3257
3258 if (GetVersion() < 0x80000000 &&
3259 _stricmp(comshell, "command.com") != 0) {
3260 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003261 x = i + strlen(s3) + strlen(cmdstring) + 1;
3262 s2 = (char *)_alloca(x);
3263 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003264 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003265 }
3266 else {
3267 /*
Tim Peters402d5982001-08-27 06:37:48 +00003268 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3269 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003270 */
Mark Hammond08501372001-01-31 07:30:29 +00003271 char modulepath[_MAX_PATH];
3272 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003273 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3274 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003275 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003276 x = i+1;
3277 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003278 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003279 strncat(modulepath,
3280 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003281 (sizeof(modulepath)/sizeof(modulepath[0]))
3282 -strlen(modulepath));
3283 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003284 /* Eeek - file-not-found - possibly an embedding
3285 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003286 */
Tim Peters5aa91602002-01-30 05:46:57 +00003287 strncpy(modulepath,
3288 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003289 sizeof(modulepath)/sizeof(modulepath[0]));
3290 if (modulepath[strlen(modulepath)-1] != '\\')
3291 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003292 strncat(modulepath,
3293 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003294 (sizeof(modulepath)/sizeof(modulepath[0]))
3295 -strlen(modulepath));
3296 /* No where else to look - raise an easily identifiable
3297 error, rather than leaving Windows to report
3298 "file not found" - as the user is probably blissfully
3299 unaware this shim EXE is used, and it will confuse them.
3300 (well, it confused me for a while ;-)
3301 */
3302 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003303 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003304 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003305 "for popen to work with your shell "
3306 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003307 szConsoleSpawn);
3308 return FALSE;
3309 }
3310 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003311 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003312 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003313 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003314
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003315 s2 = (char *)_alloca(x);
3316 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003317 /* To maintain correct argument passing semantics,
3318 we pass the command-line as it stands, and allow
3319 quoting to be applied. w9xpopen.exe will then
3320 use its argv vector, and re-quote the necessary
3321 args for the ultimate child process.
3322 */
Tim Peters75cdad52001-11-28 22:07:30 +00003323 PyOS_snprintf(
3324 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003325 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003326 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003327 s1,
3328 s3,
3329 cmdstring);
3330 }
3331 }
3332
3333 /* Could be an else here to try cmd.exe / command.com in the path
3334 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003335 else {
Tim Peters402d5982001-08-27 06:37:48 +00003336 PyErr_SetString(PyExc_RuntimeError,
3337 "Cannot locate a COMSPEC environment variable to "
3338 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003339 return FALSE;
3340 }
Tim Peters5aa91602002-01-30 05:46:57 +00003341
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003342 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3343 siStartInfo.cb = sizeof(STARTUPINFO);
3344 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3345 siStartInfo.hStdInput = hStdin;
3346 siStartInfo.hStdOutput = hStdout;
3347 siStartInfo.hStdError = hStderr;
3348 siStartInfo.wShowWindow = SW_HIDE;
3349
3350 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003351 s2,
3352 NULL,
3353 NULL,
3354 TRUE,
3355 CREATE_NEW_CONSOLE,
3356 NULL,
3357 NULL,
3358 &siStartInfo,
3359 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003360 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003361 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003362
Mark Hammondb37a3732000-08-14 04:47:33 +00003363 /* Return process handle */
3364 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003365 return TRUE;
3366 }
Tim Peters402d5982001-08-27 06:37:48 +00003367 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003368 return FALSE;
3369}
3370
3371/* The following code is based off of KB: Q190351 */
3372
3373static PyObject *
3374_PyPopen(char *cmdstring, int mode, int n)
3375{
3376 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3377 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003378 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003379
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003380 SECURITY_ATTRIBUTES saAttr;
3381 BOOL fSuccess;
3382 int fd1, fd2, fd3;
3383 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003384 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003385 PyObject *f;
3386
3387 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3388 saAttr.bInheritHandle = TRUE;
3389 saAttr.lpSecurityDescriptor = NULL;
3390
3391 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3392 return win32_error("CreatePipe", NULL);
3393
3394 /* Create new output read handle and the input write handle. Set
3395 * the inheritance properties to FALSE. Otherwise, the child inherits
3396 * the these handles; resulting in non-closeable handles to the pipes
3397 * being created. */
3398 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003399 GetCurrentProcess(), &hChildStdinWrDup, 0,
3400 FALSE,
3401 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003402 if (!fSuccess)
3403 return win32_error("DuplicateHandle", NULL);
3404
3405 /* Close the inheritable version of ChildStdin
3406 that we're using. */
3407 CloseHandle(hChildStdinWr);
3408
3409 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3410 return win32_error("CreatePipe", NULL);
3411
3412 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003413 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3414 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003415 if (!fSuccess)
3416 return win32_error("DuplicateHandle", NULL);
3417
3418 /* Close the inheritable version of ChildStdout
3419 that we're using. */
3420 CloseHandle(hChildStdoutRd);
3421
3422 if (n != POPEN_4) {
3423 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3424 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003425 fSuccess = DuplicateHandle(GetCurrentProcess(),
3426 hChildStderrRd,
3427 GetCurrentProcess(),
3428 &hChildStderrRdDup, 0,
3429 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003430 if (!fSuccess)
3431 return win32_error("DuplicateHandle", NULL);
3432 /* Close the inheritable version of ChildStdErr that we're using. */
3433 CloseHandle(hChildStderrRd);
3434 }
Tim Peters5aa91602002-01-30 05:46:57 +00003435
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003436 switch (n) {
3437 case POPEN_1:
3438 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3439 case _O_WRONLY | _O_TEXT:
3440 /* Case for writing to child Stdin in text mode. */
3441 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3442 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003443 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003444 PyFile_SetBufSize(f, 0);
3445 /* We don't care about these pipes anymore, so close them. */
3446 CloseHandle(hChildStdoutRdDup);
3447 CloseHandle(hChildStderrRdDup);
3448 break;
3449
3450 case _O_RDONLY | _O_TEXT:
3451 /* Case for reading from child Stdout in text mode. */
3452 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3453 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003454 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003455 PyFile_SetBufSize(f, 0);
3456 /* We don't care about these pipes anymore, so close them. */
3457 CloseHandle(hChildStdinWrDup);
3458 CloseHandle(hChildStderrRdDup);
3459 break;
3460
3461 case _O_RDONLY | _O_BINARY:
3462 /* Case for readinig from child Stdout in binary mode. */
3463 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3464 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003465 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003466 PyFile_SetBufSize(f, 0);
3467 /* We don't care about these pipes anymore, so close them. */
3468 CloseHandle(hChildStdinWrDup);
3469 CloseHandle(hChildStderrRdDup);
3470 break;
3471
3472 case _O_WRONLY | _O_BINARY:
3473 /* Case for writing to child Stdin in binary mode. */
3474 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3475 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003476 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003477 PyFile_SetBufSize(f, 0);
3478 /* We don't care about these pipes anymore, so close them. */
3479 CloseHandle(hChildStdoutRdDup);
3480 CloseHandle(hChildStderrRdDup);
3481 break;
3482 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003483 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003484 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003485
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003486 case POPEN_2:
3487 case POPEN_4:
3488 {
3489 char *m1, *m2;
3490 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003491
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003492 if (mode && _O_TEXT) {
3493 m1 = "r";
3494 m2 = "w";
3495 } else {
3496 m1 = "rb";
3497 m2 = "wb";
3498 }
3499
3500 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3501 f1 = _fdopen(fd1, m2);
3502 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3503 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003504 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003505 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003506 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003507 PyFile_SetBufSize(p2, 0);
3508
3509 if (n != 4)
3510 CloseHandle(hChildStderrRdDup);
3511
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003512 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003513 Py_XDECREF(p1);
3514 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003515 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003516 break;
3517 }
Tim Peters5aa91602002-01-30 05:46:57 +00003518
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003519 case POPEN_3:
3520 {
3521 char *m1, *m2;
3522 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003523
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003524 if (mode && _O_TEXT) {
3525 m1 = "r";
3526 m2 = "w";
3527 } else {
3528 m1 = "rb";
3529 m2 = "wb";
3530 }
3531
3532 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3533 f1 = _fdopen(fd1, m2);
3534 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3535 f2 = _fdopen(fd2, m1);
3536 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3537 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003538 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003539 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3540 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003541 PyFile_SetBufSize(p1, 0);
3542 PyFile_SetBufSize(p2, 0);
3543 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003544 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003545 Py_XDECREF(p1);
3546 Py_XDECREF(p2);
3547 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003548 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003549 break;
3550 }
3551 }
3552
3553 if (n == POPEN_4) {
3554 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003555 hChildStdinRd,
3556 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003557 hChildStdoutWr,
3558 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003559 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003560 }
3561 else {
3562 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003563 hChildStdinRd,
3564 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003565 hChildStderrWr,
3566 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003567 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003568 }
3569
Mark Hammondb37a3732000-08-14 04:47:33 +00003570 /*
3571 * Insert the files we've created into the process dictionary
3572 * all referencing the list with the process handle and the
3573 * initial number of files (see description below in _PyPclose).
3574 * Since if _PyPclose later tried to wait on a process when all
3575 * handles weren't closed, it could create a deadlock with the
3576 * child, we spend some energy here to try to ensure that we
3577 * either insert all file handles into the dictionary or none
3578 * at all. It's a little clumsy with the various popen modes
3579 * and variable number of files involved.
3580 */
3581 if (!_PyPopenProcs) {
3582 _PyPopenProcs = PyDict_New();
3583 }
3584
3585 if (_PyPopenProcs) {
3586 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3587 int ins_rc[3];
3588
3589 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3590 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3591
3592 procObj = PyList_New(2);
3593 hProcessObj = PyLong_FromVoidPtr(hProcess);
3594 intObj = PyInt_FromLong(file_count);
3595
3596 if (procObj && hProcessObj && intObj) {
3597 PyList_SetItem(procObj,0,hProcessObj);
3598 PyList_SetItem(procObj,1,intObj);
3599
3600 fileObj[0] = PyLong_FromVoidPtr(f1);
3601 if (fileObj[0]) {
3602 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3603 fileObj[0],
3604 procObj);
3605 }
3606 if (file_count >= 2) {
3607 fileObj[1] = PyLong_FromVoidPtr(f2);
3608 if (fileObj[1]) {
3609 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3610 fileObj[1],
3611 procObj);
3612 }
3613 }
3614 if (file_count >= 3) {
3615 fileObj[2] = PyLong_FromVoidPtr(f3);
3616 if (fileObj[2]) {
3617 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3618 fileObj[2],
3619 procObj);
3620 }
3621 }
3622
3623 if (ins_rc[0] < 0 || !fileObj[0] ||
3624 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3625 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3626 /* Something failed - remove any dictionary
3627 * entries that did make it.
3628 */
3629 if (!ins_rc[0] && fileObj[0]) {
3630 PyDict_DelItem(_PyPopenProcs,
3631 fileObj[0]);
3632 }
3633 if (!ins_rc[1] && fileObj[1]) {
3634 PyDict_DelItem(_PyPopenProcs,
3635 fileObj[1]);
3636 }
3637 if (!ins_rc[2] && fileObj[2]) {
3638 PyDict_DelItem(_PyPopenProcs,
3639 fileObj[2]);
3640 }
3641 }
3642 }
Tim Peters5aa91602002-01-30 05:46:57 +00003643
Mark Hammondb37a3732000-08-14 04:47:33 +00003644 /*
3645 * Clean up our localized references for the dictionary keys
3646 * and value since PyDict_SetItem will Py_INCREF any copies
3647 * that got placed in the dictionary.
3648 */
3649 Py_XDECREF(procObj);
3650 Py_XDECREF(fileObj[0]);
3651 Py_XDECREF(fileObj[1]);
3652 Py_XDECREF(fileObj[2]);
3653 }
3654
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003655 /* Child is launched. Close the parents copy of those pipe
3656 * handles that only the child should have open. You need to
3657 * make sure that no handles to the write end of the output pipe
3658 * are maintained in this process or else the pipe will not close
3659 * when the child process exits and the ReadFile will hang. */
3660
3661 if (!CloseHandle(hChildStdinRd))
3662 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003663
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003664 if (!CloseHandle(hChildStdoutWr))
3665 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003666
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003667 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3668 return win32_error("CloseHandle", NULL);
3669
3670 return f;
3671}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003672
3673/*
3674 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3675 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003676 *
3677 * This function uses the _PyPopenProcs dictionary in order to map the
3678 * input file pointer to information about the process that was
3679 * originally created by the popen* call that created the file pointer.
3680 * The dictionary uses the file pointer as a key (with one entry
3681 * inserted for each file returned by the original popen* call) and a
3682 * single list object as the value for all files from a single call.
3683 * The list object contains the Win32 process handle at [0], and a file
3684 * count at [1], which is initialized to the total number of file
3685 * handles using that list.
3686 *
3687 * This function closes whichever handle it is passed, and decrements
3688 * the file count in the dictionary for the process handle pointed to
3689 * by this file. On the last close (when the file count reaches zero),
3690 * this function will wait for the child process and then return its
3691 * exit code as the result of the close() operation. This permits the
3692 * files to be closed in any order - it is always the close() of the
3693 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003694 */
Tim Peters736aa322000-09-01 06:51:24 +00003695
3696 /* RED_FLAG 31-Aug-2000 Tim
3697 * This is always called (today!) between a pair of
3698 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3699 * macros. So the thread running this has no valid thread state, as
3700 * far as Python is concerned. However, this calls some Python API
3701 * functions that cannot be called safely without a valid thread
3702 * state, in particular PyDict_GetItem.
3703 * As a temporary hack (although it may last for years ...), we
3704 * *rely* on not having a valid thread state in this function, in
3705 * order to create our own "from scratch".
3706 * This will deadlock if _PyPclose is ever called by a thread
3707 * holding the global lock.
3708 */
3709
Fredrik Lundh56055a42000-07-23 19:47:12 +00003710static int _PyPclose(FILE *file)
3711{
Fredrik Lundh20318932000-07-26 17:29:12 +00003712 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003713 DWORD exit_code;
3714 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003715 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3716 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003717#ifdef WITH_THREAD
3718 PyInterpreterState* pInterpreterState;
3719 PyThreadState* pThreadState;
3720#endif
3721
Fredrik Lundh20318932000-07-26 17:29:12 +00003722 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003723 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003724 */
3725 result = fclose(file);
3726
Tim Peters736aa322000-09-01 06:51:24 +00003727#ifdef WITH_THREAD
3728 /* Bootstrap a valid thread state into existence. */
3729 pInterpreterState = PyInterpreterState_New();
3730 if (!pInterpreterState) {
3731 /* Well, we're hosed now! We don't have a thread
3732 * state, so can't call a nice error routine, or raise
3733 * an exception. Just die.
3734 */
3735 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003736 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003737 return -1; /* unreachable */
3738 }
3739 pThreadState = PyThreadState_New(pInterpreterState);
3740 if (!pThreadState) {
3741 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003742 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003743 return -1; /* unreachable */
3744 }
3745 /* Grab the global lock. Note that this will deadlock if the
3746 * current thread already has the lock! (see RED_FLAG comments
3747 * before this function)
3748 */
3749 PyEval_RestoreThread(pThreadState);
3750#endif
3751
Fredrik Lundh56055a42000-07-23 19:47:12 +00003752 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003753 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3754 (procObj = PyDict_GetItem(_PyPopenProcs,
3755 fileObj)) != NULL &&
3756 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3757 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3758
3759 hProcess = PyLong_AsVoidPtr(hProcessObj);
3760 file_count = PyInt_AsLong(intObj);
3761
3762 if (file_count > 1) {
3763 /* Still other files referencing process */
3764 file_count--;
3765 PyList_SetItem(procObj,1,
3766 PyInt_FromLong(file_count));
3767 } else {
3768 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003769 if (result != EOF &&
3770 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3771 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003772 /* Possible truncation here in 16-bit environments, but
3773 * real exit codes are just the lower byte in any event.
3774 */
3775 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003776 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003777 /* Indicate failure - this will cause the file object
3778 * to raise an I/O error and translate the last Win32
3779 * error code from errno. We do have a problem with
3780 * last errors that overlap the normal errno table,
3781 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003782 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003783 if (result != EOF) {
3784 /* If the error wasn't from the fclose(), then
3785 * set errno for the file object error handling.
3786 */
3787 errno = GetLastError();
3788 }
3789 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003790 }
3791
3792 /* Free up the native handle at this point */
3793 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003794 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003795
Mark Hammondb37a3732000-08-14 04:47:33 +00003796 /* Remove this file pointer from dictionary */
3797 PyDict_DelItem(_PyPopenProcs, fileObj);
3798
3799 if (PyDict_Size(_PyPopenProcs) == 0) {
3800 Py_DECREF(_PyPopenProcs);
3801 _PyPopenProcs = NULL;
3802 }
3803
3804 } /* if object retrieval ok */
3805
3806 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003807 } /* if _PyPopenProcs */
3808
Tim Peters736aa322000-09-01 06:51:24 +00003809#ifdef WITH_THREAD
3810 /* Tear down the thread & interpreter states.
3811 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003812 * call the thread clear & delete functions, and indeed insist on
3813 * doing that themselves. The lock must be held during the clear, but
3814 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003815 */
3816 PyInterpreterState_Clear(pInterpreterState);
3817 PyEval_ReleaseThread(pThreadState);
3818 PyInterpreterState_Delete(pInterpreterState);
3819#endif
3820
Fredrik Lundh56055a42000-07-23 19:47:12 +00003821 return result;
3822}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003823
3824#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003826posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003827{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003828 char *name;
3829 char *mode = "r";
3830 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003831 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003832 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003833 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003834 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003835 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003836 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003837 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003838 if (fp == NULL)
3839 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003840 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003841 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003842 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003843 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003844}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003845
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003846#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003847#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003849
Guido van Rossumb6775db1994-08-01 11:34:53 +00003850#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003851static char posix_setuid__doc__[] =
3852"setuid(uid) -> None\n\
3853Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003855posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003856{
3857 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003858 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003859 return NULL;
3860 if (setuid(uid) < 0)
3861 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003862 Py_INCREF(Py_None);
3863 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003864}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003865#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003867
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003868#ifdef HAVE_SETEUID
3869static char posix_seteuid__doc__[] =
3870"seteuid(uid) -> None\n\
3871Set the current process's effective user id.";
3872static PyObject *
3873posix_seteuid (PyObject *self, PyObject *args)
3874{
3875 int euid;
3876 if (!PyArg_ParseTuple(args, "i", &euid)) {
3877 return NULL;
3878 } else if (seteuid(euid) < 0) {
3879 return posix_error();
3880 } else {
3881 Py_INCREF(Py_None);
3882 return Py_None;
3883 }
3884}
3885#endif /* HAVE_SETEUID */
3886
3887#ifdef HAVE_SETEGID
3888static char posix_setegid__doc__[] =
3889"setegid(gid) -> None\n\
3890Set the current process's effective group id.";
3891static PyObject *
3892posix_setegid (PyObject *self, PyObject *args)
3893{
3894 int egid;
3895 if (!PyArg_ParseTuple(args, "i", &egid)) {
3896 return NULL;
3897 } else if (setegid(egid) < 0) {
3898 return posix_error();
3899 } else {
3900 Py_INCREF(Py_None);
3901 return Py_None;
3902 }
3903}
3904#endif /* HAVE_SETEGID */
3905
3906#ifdef HAVE_SETREUID
3907static char posix_setreuid__doc__[] =
3908"seteuid(ruid, euid) -> None\n\
3909Set the current process's real and effective user ids.";
3910static PyObject *
3911posix_setreuid (PyObject *self, PyObject *args)
3912{
3913 int ruid, euid;
3914 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3915 return NULL;
3916 } else if (setreuid(ruid, euid) < 0) {
3917 return posix_error();
3918 } else {
3919 Py_INCREF(Py_None);
3920 return Py_None;
3921 }
3922}
3923#endif /* HAVE_SETREUID */
3924
3925#ifdef HAVE_SETREGID
3926static char posix_setregid__doc__[] =
3927"setegid(rgid, egid) -> None\n\
3928Set the current process's real and effective group ids.";
3929static PyObject *
3930posix_setregid (PyObject *self, PyObject *args)
3931{
3932 int rgid, egid;
3933 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3934 return NULL;
3935 } else if (setregid(rgid, egid) < 0) {
3936 return posix_error();
3937 } else {
3938 Py_INCREF(Py_None);
3939 return Py_None;
3940 }
3941}
3942#endif /* HAVE_SETREGID */
3943
Guido van Rossumb6775db1994-08-01 11:34:53 +00003944#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003945static char posix_setgid__doc__[] =
3946"setgid(gid) -> None\n\
3947Set the current process's group id.";
3948
Barry Warsaw53699e91996-12-10 23:23:01 +00003949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003950posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003951{
3952 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003953 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003954 return NULL;
3955 if (setgid(gid) < 0)
3956 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003957 Py_INCREF(Py_None);
3958 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003959}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003960#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003961
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003962#ifdef HAVE_SETGROUPS
3963static char posix_setgroups__doc__[] =
3964"setgroups(list) -> None\n\
3965Set the groups of the current process to list.";
3966
3967static PyObject *
3968posix_setgroups(PyObject *self, PyObject *args)
3969{
3970 PyObject *groups;
3971 int i, len;
3972 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003973
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003974 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3975 return NULL;
3976 if (!PySequence_Check(groups)) {
3977 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3978 return NULL;
3979 }
3980 len = PySequence_Size(groups);
3981 if (len > MAX_GROUPS) {
3982 PyErr_SetString(PyExc_ValueError, "too many groups");
3983 return NULL;
3984 }
3985 for(i = 0; i < len; i++) {
3986 PyObject *elem;
3987 elem = PySequence_GetItem(groups, i);
3988 if (!elem)
3989 return NULL;
3990 if (!PyInt_Check(elem)) {
3991 PyErr_SetString(PyExc_TypeError,
3992 "groups must be integers");
3993 Py_DECREF(elem);
3994 return NULL;
3995 }
3996 /* XXX: check that value fits into gid_t. */
3997 grouplist[i] = PyInt_AsLong(elem);
3998 Py_DECREF(elem);
3999 }
4000
4001 if (setgroups(len, grouplist) < 0)
4002 return posix_error();
4003 Py_INCREF(Py_None);
4004 return Py_None;
4005}
4006#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004007
Guido van Rossumb6775db1994-08-01 11:34:53 +00004008#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004009static char posix_waitpid__doc__[] =
4010"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00004011Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004012
Barry Warsaw53699e91996-12-10 23:23:01 +00004013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004014posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004015{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004016 int pid, options;
4017#ifdef UNION_WAIT
4018 union wait status;
4019#define status_i (status.w_status)
4020#else
4021 int status;
4022#define status_i status
4023#endif
4024 status_i = 0;
4025
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004026 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004027 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004028 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004029 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004030 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004031 if (pid == -1)
4032 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004033 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004034 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004035}
4036
Tim Petersab034fa2002-02-01 11:27:43 +00004037#elif defined(HAVE_CWAIT)
4038
4039/* MS C has a variant of waitpid() that's usable for most purposes. */
4040static char posix_waitpid__doc__[] =
4041"waitpid(pid, options) -> (pid, status << 8)\n"
4042"Wait for completion of a given process. options is ignored on Windows.";
4043
4044static PyObject *
4045posix_waitpid(PyObject *self, PyObject *args)
4046{
4047 int pid, options;
4048 int status;
4049
4050 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4051 return NULL;
4052 Py_BEGIN_ALLOW_THREADS
4053 pid = _cwait(&status, pid, options);
4054 Py_END_ALLOW_THREADS
4055 if (pid == -1)
4056 return posix_error();
4057 else
4058 /* shift the status left a byte so this is more like the
4059 POSIX waitpid */
4060 return Py_BuildValue("ii", pid, status << 8);
4061}
4062#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004063
Guido van Rossumad0ee831995-03-01 10:34:45 +00004064#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004065static char posix_wait__doc__[] =
4066"wait() -> (pid, status)\n\
4067Wait for completion of a child process.";
4068
Barry Warsaw53699e91996-12-10 23:23:01 +00004069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004070posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004071{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004072 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004073#ifdef UNION_WAIT
4074 union wait status;
4075#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004076#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004077 int status;
4078#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004079#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004080 if (!PyArg_ParseTuple(args, ":wait"))
4081 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004082 status_i = 0;
4083 Py_BEGIN_ALLOW_THREADS
4084 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004085 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004086 if (pid == -1)
4087 return posix_error();
4088 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004089 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004090#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004091}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004092#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004093
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004094
4095static char posix_lstat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00004096"lstat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
4097 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004098Like stat(path), but do not follow symbolic links.";
4099
Barry Warsaw53699e91996-12-10 23:23:01 +00004100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004101posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004102{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004103#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004104 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004105#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004106 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004107#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004108}
4109
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004110
Guido van Rossumb6775db1994-08-01 11:34:53 +00004111#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004112static char posix_readlink__doc__[] =
4113"readlink(path) -> path\n\
4114Return a string representing the path to which the symbolic link points.";
4115
Barry Warsaw53699e91996-12-10 23:23:01 +00004116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004117posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004118{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004119 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004120 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004121 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004122 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004123 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004124 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004125 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004126 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004127 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004128 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004129 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004130}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004131#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004133
Guido van Rossumb6775db1994-08-01 11:34:53 +00004134#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004135static char posix_symlink__doc__[] =
4136"symlink(src, dst) -> None\n\
4137Create a symbolic link.";
4138
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004140posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004141{
Mark Hammondef8b6542001-05-13 08:04:26 +00004142 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004143}
4144#endif /* HAVE_SYMLINK */
4145
4146
4147#ifdef HAVE_TIMES
4148#ifndef HZ
4149#define HZ 60 /* Universal constant :-) */
4150#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004151
Guido van Rossumd48f2521997-12-05 22:19:34 +00004152#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4153static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004154system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004155{
4156 ULONG value = 0;
4157
4158 Py_BEGIN_ALLOW_THREADS
4159 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4160 Py_END_ALLOW_THREADS
4161
4162 return value;
4163}
4164
4165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004166posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004167{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004168 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004169 return NULL;
4170
4171 /* Currently Only Uptime is Provided -- Others Later */
4172 return Py_BuildValue("ddddd",
4173 (double)0 /* t.tms_utime / HZ */,
4174 (double)0 /* t.tms_stime / HZ */,
4175 (double)0 /* t.tms_cutime / HZ */,
4176 (double)0 /* t.tms_cstime / HZ */,
4177 (double)system_uptime() / 1000);
4178}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004179#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004181posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004182{
4183 struct tms t;
4184 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004185 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004186 return NULL;
4187 errno = 0;
4188 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004189 if (c == (clock_t) -1)
4190 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004191 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004192 (double)t.tms_utime / HZ,
4193 (double)t.tms_stime / HZ,
4194 (double)t.tms_cutime / HZ,
4195 (double)t.tms_cstime / HZ,
4196 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004197}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004198#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004199#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004200
4201
Guido van Rossum87755a21996-09-07 00:59:43 +00004202#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004203#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004205posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004206{
4207 FILETIME create, exit, kernel, user;
4208 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004209 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004210 return NULL;
4211 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004212 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4213 /* The fields of a FILETIME structure are the hi and lo part
4214 of a 64-bit value expressed in 100 nanosecond units.
4215 1e7 is one second in such units; 1e-7 the inverse.
4216 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4217 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004218 return Py_BuildValue(
4219 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004220 (double)(kernel.dwHighDateTime*429.4967296 +
4221 kernel.dwLowDateTime*1e-7),
4222 (double)(user.dwHighDateTime*429.4967296 +
4223 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004224 (double)0,
4225 (double)0,
4226 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004227}
Guido van Rossum8d665e61996-06-26 18:22:49 +00004228#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004229
4230#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00004231static char posix_times__doc__[] =
4232"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
4233Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004234#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004236
Guido van Rossumb6775db1994-08-01 11:34:53 +00004237#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004238static char posix_setsid__doc__[] =
4239"setsid() -> None\n\
4240Call the system call setsid().";
4241
Barry Warsaw53699e91996-12-10 23:23:01 +00004242static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004243posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004244{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004245 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004246 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004247 if (setsid() < 0)
4248 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004249 Py_INCREF(Py_None);
4250 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004251}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004252#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004253
Guido van Rossumb6775db1994-08-01 11:34:53 +00004254#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004255static char posix_setpgid__doc__[] =
4256"setpgid(pid, pgrp) -> None\n\
4257Call the system call setpgid().";
4258
Barry Warsaw53699e91996-12-10 23:23:01 +00004259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004260posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004261{
4262 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004263 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004264 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004265 if (setpgid(pid, pgrp) < 0)
4266 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004267 Py_INCREF(Py_None);
4268 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004269}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004270#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004271
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004272
Guido van Rossumb6775db1994-08-01 11:34:53 +00004273#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004274static char posix_tcgetpgrp__doc__[] =
4275"tcgetpgrp(fd) -> pgid\n\
4276Return the process group associated with the terminal given by a fd.";
4277
Barry Warsaw53699e91996-12-10 23:23:01 +00004278static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004279posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004280{
4281 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004282 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004283 return NULL;
4284 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004285 if (pgid < 0)
4286 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004287 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004288}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004289#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004291
Guido van Rossumb6775db1994-08-01 11:34:53 +00004292#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004293static char posix_tcsetpgrp__doc__[] =
4294"tcsetpgrp(fd, pgid) -> None\n\
4295Set the process group associated with the terminal given by a fd.";
4296
Barry Warsaw53699e91996-12-10 23:23:01 +00004297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004298posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004299{
4300 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004301 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004302 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004303 if (tcsetpgrp(fd, pgid) < 0)
4304 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004305 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004306 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004307}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004308#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004309
Guido van Rossum687dd131993-05-17 08:34:16 +00004310/* Functions acting on file descriptors */
4311
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004312static char posix_open__doc__[] =
4313"open(filename, flag [, mode=0777]) -> fd\n\
4314Open a file (for low level IO).";
4315
Barry Warsaw53699e91996-12-10 23:23:01 +00004316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004317posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004318{
Mark Hammondef8b6542001-05-13 08:04:26 +00004319 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004320 int flag;
4321 int mode = 0777;
4322 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004323 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004324 Py_FileSystemDefaultEncoding, &file,
4325 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004326 return NULL;
4327
Barry Warsaw53699e91996-12-10 23:23:01 +00004328 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004329 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004330 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004331 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004332 return posix_error_with_allocated_filename(file);
4333 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004334 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004335}
4336
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004337
4338static char posix_close__doc__[] =
4339"close(fd) -> None\n\
4340Close a file descriptor (for low level IO).";
4341
Barry Warsaw53699e91996-12-10 23:23:01 +00004342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004343posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004344{
4345 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004346 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004347 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004348 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004349 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004350 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004351 if (res < 0)
4352 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004353 Py_INCREF(Py_None);
4354 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004355}
4356
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004357
4358static char posix_dup__doc__[] =
4359"dup(fd) -> fd2\n\
4360Return a duplicate of a file descriptor.";
4361
Barry Warsaw53699e91996-12-10 23:23:01 +00004362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004363posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004364{
4365 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004366 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004367 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004368 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004369 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004370 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004371 if (fd < 0)
4372 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004373 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004374}
4375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004376
4377static char posix_dup2__doc__[] =
4378"dup2(fd, fd2) -> None\n\
4379Duplicate file descriptor.";
4380
Barry Warsaw53699e91996-12-10 23:23:01 +00004381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004382posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004383{
4384 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004385 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004386 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004387 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004388 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004389 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004390 if (res < 0)
4391 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004392 Py_INCREF(Py_None);
4393 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004394}
4395
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004396
4397static char posix_lseek__doc__[] =
4398"lseek(fd, pos, how) -> newpos\n\
4399Set the current position of a file descriptor.";
4400
Barry Warsaw53699e91996-12-10 23:23:01 +00004401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004402posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004403{
4404 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00004405#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004406 LONG_LONG pos, res;
4407#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004408 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004409#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004410 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004411 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004412 return NULL;
4413#ifdef SEEK_SET
4414 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4415 switch (how) {
4416 case 0: how = SEEK_SET; break;
4417 case 1: how = SEEK_CUR; break;
4418 case 2: how = SEEK_END; break;
4419 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004420#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004421
4422#if !defined(HAVE_LARGEFILE_SUPPORT)
4423 pos = PyInt_AsLong(posobj);
4424#else
4425 pos = PyLong_Check(posobj) ?
4426 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4427#endif
4428 if (PyErr_Occurred())
4429 return NULL;
4430
Barry Warsaw53699e91996-12-10 23:23:01 +00004431 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00004432#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004433 res = _lseeki64(fd, pos, how);
4434#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004435 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004436#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004437 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004438 if (res < 0)
4439 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004440
4441#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004442 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004443#else
4444 return PyLong_FromLongLong(res);
4445#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004446}
4447
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004448
4449static char posix_read__doc__[] =
4450"read(fd, buffersize) -> string\n\
4451Read a file descriptor.";
4452
Barry Warsaw53699e91996-12-10 23:23:01 +00004453static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004454posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004455{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004456 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004457 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004458 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004459 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004460 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004461 if (buffer == NULL)
4462 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004463 Py_BEGIN_ALLOW_THREADS
4464 n = read(fd, PyString_AsString(buffer), size);
4465 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004466 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004467 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004468 return posix_error();
4469 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004470 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004471 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004472 return buffer;
4473}
4474
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004475
4476static char posix_write__doc__[] =
4477"write(fd, string) -> byteswritten\n\
4478Write a string to a file descriptor.";
4479
Barry Warsaw53699e91996-12-10 23:23:01 +00004480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004481posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004482{
4483 int fd, size;
4484 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004485 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004486 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004487 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004488 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004489 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004490 if (size < 0)
4491 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004492 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004493}
4494
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004495
4496static char posix_fstat__doc__[]=
4497"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
4498Like stat(), but for an open file descriptor.";
4499
Barry Warsaw53699e91996-12-10 23:23:01 +00004500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004501posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004502{
4503 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004504 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004505 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004506 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004507 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004508 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004509 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004510 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004511 if (res != 0)
4512 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004513
Fred Drake699f3522000-06-29 21:12:41 +00004514 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004515}
4516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004517
4518static char posix_fdopen__doc__[] =
4519"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
4520Return an open file object connected to a file descriptor.";
4521
Barry Warsaw53699e91996-12-10 23:23:01 +00004522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004523posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004524{
Guido van Rossum687dd131993-05-17 08:34:16 +00004525 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004526 char *mode = "r";
4527 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004528 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004529 PyObject *f;
4530 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004531 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004532
Barry Warsaw53699e91996-12-10 23:23:01 +00004533 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004534 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004535 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004536 if (fp == NULL)
4537 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004538 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004539 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004540 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004541 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004542}
4543
Skip Montanaro1517d842000-07-19 14:34:14 +00004544static char posix_isatty__doc__[] =
4545"isatty(fd) -> Boolean\n\
4546Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00004547connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00004548
4549static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004550posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004551{
4552 int fd;
4553 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4554 return NULL;
4555 return Py_BuildValue("i", isatty(fd));
4556}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004557
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004558#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004559static char posix_pipe__doc__[] =
4560"pipe() -> (read_end, write_end)\n\
4561Create a pipe.";
4562
Barry Warsaw53699e91996-12-10 23:23:01 +00004563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004564posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004565{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004566#if defined(PYOS_OS2)
4567 HFILE read, write;
4568 APIRET rc;
4569
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004570 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004571 return NULL;
4572
4573 Py_BEGIN_ALLOW_THREADS
4574 rc = DosCreatePipe( &read, &write, 4096);
4575 Py_END_ALLOW_THREADS
4576 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004577 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004578
4579 return Py_BuildValue("(ii)", read, write);
4580#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00004581#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00004582 int fds[2];
4583 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004584 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004585 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004586 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004587 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004588 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004589 if (res != 0)
4590 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004591 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004592#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00004593 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004594 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004595 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004596 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004597 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004598 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004599 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004600 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004601 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004602 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004603 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4604 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004605 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004606#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004607#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004608}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004609#endif /* HAVE_PIPE */
4610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004611
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004612#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004613static char posix_mkfifo__doc__[] =
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004614"mkfifo(filename, [, mode=0666]) -> None\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004615Create a FIFO (a POSIX named pipe).";
4616
Barry Warsaw53699e91996-12-10 23:23:01 +00004617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004618posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004619{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004620 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004621 int mode = 0666;
4622 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004623 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004624 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004625 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004626 res = mkfifo(filename, mode);
4627 Py_END_ALLOW_THREADS
4628 if (res < 0)
4629 return posix_error();
4630 Py_INCREF(Py_None);
4631 return Py_None;
4632}
4633#endif
4634
4635
4636#ifdef HAVE_MKNOD
4637static char posix_mknod__doc__[] =
4638"mknod(filename, [, mode=0600, major, minor]) -> None\n\
4639Create a filesystem node (file, device special file or named pipe)\n\
4640named filename. mode specifies both the permissions to use and the\n\
4641type of node to be created, being combined (bitwise OR) with one of\n\
4642S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4643major and minor define the newly created device special file, otherwise\n\
4644they are ignored.";
4645
4646
4647static PyObject *
4648posix_mknod(PyObject *self, PyObject *args)
4649{
4650 char *filename;
4651 int mode = 0600;
4652 int major = 0;
4653 int minor = 0;
4654 int res;
4655 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4656 &mode, &major, &minor))
4657 return NULL;
4658 Py_BEGIN_ALLOW_THREADS
4659 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004660 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004661 if (res < 0)
4662 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004663 Py_INCREF(Py_None);
4664 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004665}
4666#endif
4667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004668
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004669#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004670static char posix_ftruncate__doc__[] =
4671"ftruncate(fd, length) -> None\n\
4672Truncate a file to a specified length.";
4673
Barry Warsaw53699e91996-12-10 23:23:01 +00004674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004675posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004676{
4677 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004678 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004679 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004680 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004681
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004682 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004683 return NULL;
4684
4685#if !defined(HAVE_LARGEFILE_SUPPORT)
4686 length = PyInt_AsLong(lenobj);
4687#else
4688 length = PyLong_Check(lenobj) ?
4689 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4690#endif
4691 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004692 return NULL;
4693
Barry Warsaw53699e91996-12-10 23:23:01 +00004694 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004695 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004696 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004697 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004698 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004699 return NULL;
4700 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004701 Py_INCREF(Py_None);
4702 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004703}
4704#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004705
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004706#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004707static char posix_putenv__doc__[] =
4708"putenv(key, value) -> None\n\
4709Change or add an environment variable.";
4710
Fred Drake762e2061999-08-26 17:23:54 +00004711/* Save putenv() parameters as values here, so we can collect them when they
4712 * get re-set with another call for the same key. */
4713static PyObject *posix_putenv_garbage;
4714
Tim Peters5aa91602002-01-30 05:46:57 +00004715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004716posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004717{
4718 char *s1, *s2;
4719 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004720 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004721 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004722
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004723 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004724 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004725
4726#if defined(PYOS_OS2)
4727 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4728 APIRET rc;
4729
4730 if (strlen(s2) == 0) /* If New Value is an Empty String */
4731 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4732
4733 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4734 if (rc != NO_ERROR)
4735 return os2_error(rc);
4736
4737 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4738 APIRET rc;
4739
4740 if (strlen(s2) == 0) /* If New Value is an Empty String */
4741 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4742
4743 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4744 if (rc != NO_ERROR)
4745 return os2_error(rc);
4746 } else {
4747#endif
4748
Fred Drake762e2061999-08-26 17:23:54 +00004749 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004750 len = strlen(s1) + strlen(s2) + 2;
4751 /* len includes space for a trailing \0; the size arg to
4752 PyString_FromStringAndSize does not count that */
4753 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004754 if (newstr == NULL)
4755 return PyErr_NoMemory();
4756 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004757 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004758 if (putenv(new)) {
4759 posix_error();
4760 return NULL;
4761 }
Fred Drake762e2061999-08-26 17:23:54 +00004762 /* Install the first arg and newstr in posix_putenv_garbage;
4763 * this will cause previous value to be collected. This has to
4764 * happen after the real putenv() call because the old value
4765 * was still accessible until then. */
4766 if (PyDict_SetItem(posix_putenv_garbage,
4767 PyTuple_GET_ITEM(args, 0), newstr)) {
4768 /* really not much we can do; just leak */
4769 PyErr_Clear();
4770 }
4771 else {
4772 Py_DECREF(newstr);
4773 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004774
4775#if defined(PYOS_OS2)
4776 }
4777#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004778 Py_INCREF(Py_None);
4779 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004780}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004781#endif /* putenv */
4782
Guido van Rossumc524d952001-10-19 01:31:59 +00004783#ifdef HAVE_UNSETENV
4784static char posix_unsetenv__doc__[] =
4785"unsetenv(key) -> None\n\
4786Delete an environment variable.";
4787
4788static PyObject *
4789posix_unsetenv(PyObject *self, PyObject *args)
4790{
4791 char *s1;
4792
4793 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4794 return NULL;
4795
4796 unsetenv(s1);
4797
4798 /* Remove the key from posix_putenv_garbage;
4799 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004800 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004801 * old value was still accessible until then.
4802 */
4803 if (PyDict_DelItem(posix_putenv_garbage,
4804 PyTuple_GET_ITEM(args, 0))) {
4805 /* really not much we can do; just leak */
4806 PyErr_Clear();
4807 }
4808
4809 Py_INCREF(Py_None);
4810 return Py_None;
4811}
4812#endif /* unsetenv */
4813
Guido van Rossumb6a47161997-09-15 22:54:34 +00004814#ifdef HAVE_STRERROR
4815static char posix_strerror__doc__[] =
4816"strerror(code) -> string\n\
4817Translate an error code to a message string.";
4818
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004820posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004821{
4822 int code;
4823 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004824 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004825 return NULL;
4826 message = strerror(code);
4827 if (message == NULL) {
4828 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004829 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004830 return NULL;
4831 }
4832 return PyString_FromString(message);
4833}
4834#endif /* strerror */
4835
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004836
Guido van Rossumc9641791998-08-04 15:26:23 +00004837#ifdef HAVE_SYS_WAIT_H
4838
4839#ifdef WIFSTOPPED
4840static char posix_WIFSTOPPED__doc__[] =
4841"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004842Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004843
4844static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004845posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004846{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004847#ifdef UNION_WAIT
4848 union wait status;
4849#define status_i (status.w_status)
4850#else
4851 int status;
4852#define status_i status
4853#endif
4854 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004855
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004856 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004857 {
4858 return NULL;
4859 }
Tim Peters5aa91602002-01-30 05:46:57 +00004860
Guido van Rossumc9641791998-08-04 15:26:23 +00004861 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004862#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004863}
4864#endif /* WIFSTOPPED */
4865
4866#ifdef WIFSIGNALED
4867static char posix_WIFSIGNALED__doc__[] =
4868"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004869Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004870
4871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004872posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004873{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004874#ifdef UNION_WAIT
4875 union wait status;
4876#define status_i (status.w_status)
4877#else
4878 int status;
4879#define status_i status
4880#endif
4881 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004882
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004883 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004884 {
4885 return NULL;
4886 }
Tim Peters5aa91602002-01-30 05:46:57 +00004887
Guido van Rossumc9641791998-08-04 15:26:23 +00004888 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004889#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004890}
4891#endif /* WIFSIGNALED */
4892
4893#ifdef WIFEXITED
4894static char posix_WIFEXITED__doc__[] =
4895"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004896Return true if the process returning 'status' exited using the exit()\n\
4897system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004898
4899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004900posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004901{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004902#ifdef UNION_WAIT
4903 union wait status;
4904#define status_i (status.w_status)
4905#else
4906 int status;
4907#define status_i status
4908#endif
4909 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004910
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004911 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004912 {
4913 return NULL;
4914 }
Tim Peters5aa91602002-01-30 05:46:57 +00004915
Guido van Rossumc9641791998-08-04 15:26:23 +00004916 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004917#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004918}
4919#endif /* WIFEXITED */
4920
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004921#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004922static char posix_WEXITSTATUS__doc__[] =
4923"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004924Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004925
4926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004927posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004928{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004929#ifdef UNION_WAIT
4930 union wait status;
4931#define status_i (status.w_status)
4932#else
4933 int status;
4934#define status_i status
4935#endif
4936 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004937
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004938 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004939 {
4940 return NULL;
4941 }
Tim Peters5aa91602002-01-30 05:46:57 +00004942
Guido van Rossumc9641791998-08-04 15:26:23 +00004943 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004944#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004945}
4946#endif /* WEXITSTATUS */
4947
4948#ifdef WTERMSIG
4949static char posix_WTERMSIG__doc__[] =
4950"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004951Return the signal that terminated the process that provided the 'status'\n\
4952value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004953
4954static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004955posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004956{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004957#ifdef UNION_WAIT
4958 union wait status;
4959#define status_i (status.w_status)
4960#else
4961 int status;
4962#define status_i status
4963#endif
4964 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004965
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004966 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004967 {
4968 return NULL;
4969 }
Tim Peters5aa91602002-01-30 05:46:57 +00004970
Guido van Rossumc9641791998-08-04 15:26:23 +00004971 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004972#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004973}
4974#endif /* WTERMSIG */
4975
4976#ifdef WSTOPSIG
4977static char posix_WSTOPSIG__doc__[] =
4978"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004979Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004980
4981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004982posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004983{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004984#ifdef UNION_WAIT
4985 union wait status;
4986#define status_i (status.w_status)
4987#else
4988 int status;
4989#define status_i status
4990#endif
4991 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004992
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004993 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004994 {
4995 return NULL;
4996 }
Tim Peters5aa91602002-01-30 05:46:57 +00004997
Guido van Rossumc9641791998-08-04 15:26:23 +00004998 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004999#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005000}
5001#endif /* WSTOPSIG */
5002
5003#endif /* HAVE_SYS_WAIT_H */
5004
5005
Guido van Rossum94f6f721999-01-06 18:42:14 +00005006#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005007#ifdef _SCO_DS
5008/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5009 needed definitions in sys/statvfs.h */
5010#define _SVID3
5011#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005012#include <sys/statvfs.h>
5013
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005014static PyObject*
5015_pystatvfs_fromstructstatvfs(struct statvfs st) {
5016 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5017 if (v == NULL)
5018 return NULL;
5019
5020#if !defined(HAVE_LARGEFILE_SUPPORT)
5021 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5022 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5023 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5024 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5025 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5026 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5027 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5028 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5029 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5030 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5031#else
5032 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5033 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005034 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005035 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005036 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005037 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5038 PyStructSequence_SET_ITEM(v, 4,
5039 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005040 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005041 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005042 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005043 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005044 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005045 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5046 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5047 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5048#endif
5049
5050 return v;
5051}
5052
Guido van Rossum94f6f721999-01-06 18:42:14 +00005053static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005054"fstatvfs(fd) -> \n\
5055 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005056Perform an fstatvfs system call on the given fd.";
5057
5058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005059posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005060{
5061 int fd, res;
5062 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005063
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005064 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005065 return NULL;
5066 Py_BEGIN_ALLOW_THREADS
5067 res = fstatvfs(fd, &st);
5068 Py_END_ALLOW_THREADS
5069 if (res != 0)
5070 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005071
5072 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005073}
5074#endif /* HAVE_FSTATVFS */
5075
5076
5077#if defined(HAVE_STATVFS)
5078#include <sys/statvfs.h>
5079
5080static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005081"statvfs(path) -> \n\
5082 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005083Perform a statvfs system call on the given path.";
5084
5085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005086posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005087{
5088 char *path;
5089 int res;
5090 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005091 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005092 return NULL;
5093 Py_BEGIN_ALLOW_THREADS
5094 res = statvfs(path, &st);
5095 Py_END_ALLOW_THREADS
5096 if (res != 0)
5097 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005098
5099 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005100}
5101#endif /* HAVE_STATVFS */
5102
5103
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005104#ifdef HAVE_TEMPNAM
5105static char posix_tempnam__doc__[] = "\
5106tempnam([dir[, prefix]]) -> string\n\
5107Return a unique name for a temporary file.\n\
5108The directory and a short may be specified as strings; they may be omitted\n\
5109or None if not needed.";
5110
5111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005112posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005113{
5114 PyObject *result = NULL;
5115 char *dir = NULL;
5116 char *pfx = NULL;
5117 char *name;
5118
5119 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5120 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005121
5122 if (PyErr_Warn(PyExc_RuntimeWarning,
5123 "tempnam is a potential security risk to your program") < 0)
5124 return NULL;
5125
Fred Drake78b71c22001-07-17 20:37:36 +00005126#ifdef MS_WIN32
5127 name = _tempnam(dir, pfx);
5128#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005129 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005130#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005131 if (name == NULL)
5132 return PyErr_NoMemory();
5133 result = PyString_FromString(name);
5134 free(name);
5135 return result;
5136}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005137#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005138
5139
5140#ifdef HAVE_TMPFILE
5141static char posix_tmpfile__doc__[] = "\
5142tmpfile() -> file object\n\
5143Create a temporary file with no directory entries.";
5144
5145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005146posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005147{
5148 FILE *fp;
5149
5150 if (!PyArg_ParseTuple(args, ":tmpfile"))
5151 return NULL;
5152 fp = tmpfile();
5153 if (fp == NULL)
5154 return posix_error();
5155 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
5156}
5157#endif
5158
5159
5160#ifdef HAVE_TMPNAM
5161static char posix_tmpnam__doc__[] = "\
5162tmpnam() -> string\n\
5163Return a unique name for a temporary file.";
5164
5165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005166posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005167{
5168 char buffer[L_tmpnam];
5169 char *name;
5170
5171 if (!PyArg_ParseTuple(args, ":tmpnam"))
5172 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005173
5174 if (PyErr_Warn(PyExc_RuntimeWarning,
5175 "tmpnam is a potential security risk to your program") < 0)
5176 return NULL;
5177
Greg Wardb48bc172000-03-01 21:51:56 +00005178#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005179 name = tmpnam_r(buffer);
5180#else
5181 name = tmpnam(buffer);
5182#endif
5183 if (name == NULL) {
5184 PyErr_SetObject(PyExc_OSError,
5185 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005186#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005187 "unexpected NULL from tmpnam_r"
5188#else
5189 "unexpected NULL from tmpnam"
5190#endif
5191 ));
5192 return NULL;
5193 }
5194 return PyString_FromString(buffer);
5195}
5196#endif
5197
5198
Fred Drakec9680921999-12-13 16:37:25 +00005199/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5200 * It maps strings representing configuration variable names to
5201 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005202 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005203 * rarely-used constants. There are three separate tables that use
5204 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005205 *
5206 * This code is always included, even if none of the interfaces that
5207 * need it are included. The #if hackery needed to avoid it would be
5208 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005209 */
5210struct constdef {
5211 char *name;
5212 long value;
5213};
5214
Fred Drake12c6e2d1999-12-14 21:25:03 +00005215static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005216conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5217 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005218{
5219 if (PyInt_Check(arg)) {
5220 *valuep = PyInt_AS_LONG(arg);
5221 return 1;
5222 }
5223 if (PyString_Check(arg)) {
5224 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005225 size_t lo = 0;
5226 size_t mid;
5227 size_t hi = tablesize;
5228 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005229 char *confname = PyString_AS_STRING(arg);
5230 while (lo < hi) {
5231 mid = (lo + hi) / 2;
5232 cmp = strcmp(confname, table[mid].name);
5233 if (cmp < 0)
5234 hi = mid;
5235 else if (cmp > 0)
5236 lo = mid + 1;
5237 else {
5238 *valuep = table[mid].value;
5239 return 1;
5240 }
5241 }
5242 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5243 }
5244 else
5245 PyErr_SetString(PyExc_TypeError,
5246 "configuration names must be strings or integers");
5247 return 0;
5248}
5249
5250
5251#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5252static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005253#ifdef _PC_ABI_AIO_XFER_MAX
5254 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5255#endif
5256#ifdef _PC_ABI_ASYNC_IO
5257 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5258#endif
Fred Drakec9680921999-12-13 16:37:25 +00005259#ifdef _PC_ASYNC_IO
5260 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5261#endif
5262#ifdef _PC_CHOWN_RESTRICTED
5263 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5264#endif
5265#ifdef _PC_FILESIZEBITS
5266 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5267#endif
5268#ifdef _PC_LAST
5269 {"PC_LAST", _PC_LAST},
5270#endif
5271#ifdef _PC_LINK_MAX
5272 {"PC_LINK_MAX", _PC_LINK_MAX},
5273#endif
5274#ifdef _PC_MAX_CANON
5275 {"PC_MAX_CANON", _PC_MAX_CANON},
5276#endif
5277#ifdef _PC_MAX_INPUT
5278 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5279#endif
5280#ifdef _PC_NAME_MAX
5281 {"PC_NAME_MAX", _PC_NAME_MAX},
5282#endif
5283#ifdef _PC_NO_TRUNC
5284 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5285#endif
5286#ifdef _PC_PATH_MAX
5287 {"PC_PATH_MAX", _PC_PATH_MAX},
5288#endif
5289#ifdef _PC_PIPE_BUF
5290 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5291#endif
5292#ifdef _PC_PRIO_IO
5293 {"PC_PRIO_IO", _PC_PRIO_IO},
5294#endif
5295#ifdef _PC_SOCK_MAXBUF
5296 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5297#endif
5298#ifdef _PC_SYNC_IO
5299 {"PC_SYNC_IO", _PC_SYNC_IO},
5300#endif
5301#ifdef _PC_VDISABLE
5302 {"PC_VDISABLE", _PC_VDISABLE},
5303#endif
5304};
5305
Fred Drakec9680921999-12-13 16:37:25 +00005306static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005307conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005308{
5309 return conv_confname(arg, valuep, posix_constants_pathconf,
5310 sizeof(posix_constants_pathconf)
5311 / sizeof(struct constdef));
5312}
5313#endif
5314
5315#ifdef HAVE_FPATHCONF
5316static char posix_fpathconf__doc__[] = "\
5317fpathconf(fd, name) -> integer\n\
5318Return the configuration limit name for the file descriptor fd.\n\
5319If there is no limit, return -1.";
5320
5321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005322posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005323{
5324 PyObject *result = NULL;
5325 int name, fd;
5326
Fred Drake12c6e2d1999-12-14 21:25:03 +00005327 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5328 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005329 long limit;
5330
5331 errno = 0;
5332 limit = fpathconf(fd, name);
5333 if (limit == -1 && errno != 0)
5334 posix_error();
5335 else
5336 result = PyInt_FromLong(limit);
5337 }
5338 return result;
5339}
5340#endif
5341
5342
5343#ifdef HAVE_PATHCONF
5344static char posix_pathconf__doc__[] = "\
5345pathconf(path, name) -> integer\n\
5346Return the configuration limit name for the file or directory path.\n\
5347If there is no limit, return -1.";
5348
5349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005350posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005351{
5352 PyObject *result = NULL;
5353 int name;
5354 char *path;
5355
5356 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5357 conv_path_confname, &name)) {
5358 long limit;
5359
5360 errno = 0;
5361 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005362 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005363 if (errno == EINVAL)
5364 /* could be a path or name problem */
5365 posix_error();
5366 else
5367 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005368 }
Fred Drakec9680921999-12-13 16:37:25 +00005369 else
5370 result = PyInt_FromLong(limit);
5371 }
5372 return result;
5373}
5374#endif
5375
5376#ifdef HAVE_CONFSTR
5377static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005378#ifdef _CS_ARCHITECTURE
5379 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5380#endif
5381#ifdef _CS_HOSTNAME
5382 {"CS_HOSTNAME", _CS_HOSTNAME},
5383#endif
5384#ifdef _CS_HW_PROVIDER
5385 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5386#endif
5387#ifdef _CS_HW_SERIAL
5388 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5389#endif
5390#ifdef _CS_INITTAB_NAME
5391 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5392#endif
Fred Drakec9680921999-12-13 16:37:25 +00005393#ifdef _CS_LFS64_CFLAGS
5394 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5395#endif
5396#ifdef _CS_LFS64_LDFLAGS
5397 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5398#endif
5399#ifdef _CS_LFS64_LIBS
5400 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5401#endif
5402#ifdef _CS_LFS64_LINTFLAGS
5403 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5404#endif
5405#ifdef _CS_LFS_CFLAGS
5406 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5407#endif
5408#ifdef _CS_LFS_LDFLAGS
5409 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5410#endif
5411#ifdef _CS_LFS_LIBS
5412 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5413#endif
5414#ifdef _CS_LFS_LINTFLAGS
5415 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5416#endif
Fred Draked86ed291999-12-15 15:34:33 +00005417#ifdef _CS_MACHINE
5418 {"CS_MACHINE", _CS_MACHINE},
5419#endif
Fred Drakec9680921999-12-13 16:37:25 +00005420#ifdef _CS_PATH
5421 {"CS_PATH", _CS_PATH},
5422#endif
Fred Draked86ed291999-12-15 15:34:33 +00005423#ifdef _CS_RELEASE
5424 {"CS_RELEASE", _CS_RELEASE},
5425#endif
5426#ifdef _CS_SRPC_DOMAIN
5427 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5428#endif
5429#ifdef _CS_SYSNAME
5430 {"CS_SYSNAME", _CS_SYSNAME},
5431#endif
5432#ifdef _CS_VERSION
5433 {"CS_VERSION", _CS_VERSION},
5434#endif
Fred Drakec9680921999-12-13 16:37:25 +00005435#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5436 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5437#endif
5438#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5439 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5440#endif
5441#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5442 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5443#endif
5444#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5445 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5446#endif
5447#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5448 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5449#endif
5450#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5451 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5452#endif
5453#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5454 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5455#endif
5456#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5457 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5458#endif
5459#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5460 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5461#endif
5462#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5463 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5464#endif
5465#ifdef _CS_XBS5_LP64_OFF64_LIBS
5466 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5467#endif
5468#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5469 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5470#endif
5471#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5472 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5473#endif
5474#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5475 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5476#endif
5477#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5478 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5479#endif
5480#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5481 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5482#endif
Fred Draked86ed291999-12-15 15:34:33 +00005483#ifdef _MIPS_CS_AVAIL_PROCESSORS
5484 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5485#endif
5486#ifdef _MIPS_CS_BASE
5487 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5488#endif
5489#ifdef _MIPS_CS_HOSTID
5490 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5491#endif
5492#ifdef _MIPS_CS_HW_NAME
5493 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5494#endif
5495#ifdef _MIPS_CS_NUM_PROCESSORS
5496 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5497#endif
5498#ifdef _MIPS_CS_OSREL_MAJ
5499 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5500#endif
5501#ifdef _MIPS_CS_OSREL_MIN
5502 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5503#endif
5504#ifdef _MIPS_CS_OSREL_PATCH
5505 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5506#endif
5507#ifdef _MIPS_CS_OS_NAME
5508 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5509#endif
5510#ifdef _MIPS_CS_OS_PROVIDER
5511 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5512#endif
5513#ifdef _MIPS_CS_PROCESSORS
5514 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5515#endif
5516#ifdef _MIPS_CS_SERIAL
5517 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5518#endif
5519#ifdef _MIPS_CS_VENDOR
5520 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5521#endif
Fred Drakec9680921999-12-13 16:37:25 +00005522};
5523
5524static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005525conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005526{
5527 return conv_confname(arg, valuep, posix_constants_confstr,
5528 sizeof(posix_constants_confstr)
5529 / sizeof(struct constdef));
5530}
5531
5532static char posix_confstr__doc__[] = "\
5533confstr(name) -> string\n\
5534Return a string-valued system configuration variable.";
5535
5536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005537posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005538{
5539 PyObject *result = NULL;
5540 int name;
5541 char buffer[64];
5542
5543 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5544 int len = confstr(name, buffer, sizeof(buffer));
5545
Fred Drakec9680921999-12-13 16:37:25 +00005546 errno = 0;
5547 if (len == 0) {
5548 if (errno != 0)
5549 posix_error();
5550 else
5551 result = PyString_FromString("");
5552 }
5553 else {
5554 if (len >= sizeof(buffer)) {
5555 result = PyString_FromStringAndSize(NULL, len);
5556 if (result != NULL)
5557 confstr(name, PyString_AS_STRING(result), len+1);
5558 }
5559 else
5560 result = PyString_FromString(buffer);
5561 }
5562 }
5563 return result;
5564}
5565#endif
5566
5567
5568#ifdef HAVE_SYSCONF
5569static struct constdef posix_constants_sysconf[] = {
5570#ifdef _SC_2_CHAR_TERM
5571 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5572#endif
5573#ifdef _SC_2_C_BIND
5574 {"SC_2_C_BIND", _SC_2_C_BIND},
5575#endif
5576#ifdef _SC_2_C_DEV
5577 {"SC_2_C_DEV", _SC_2_C_DEV},
5578#endif
5579#ifdef _SC_2_C_VERSION
5580 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5581#endif
5582#ifdef _SC_2_FORT_DEV
5583 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5584#endif
5585#ifdef _SC_2_FORT_RUN
5586 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5587#endif
5588#ifdef _SC_2_LOCALEDEF
5589 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5590#endif
5591#ifdef _SC_2_SW_DEV
5592 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5593#endif
5594#ifdef _SC_2_UPE
5595 {"SC_2_UPE", _SC_2_UPE},
5596#endif
5597#ifdef _SC_2_VERSION
5598 {"SC_2_VERSION", _SC_2_VERSION},
5599#endif
Fred Draked86ed291999-12-15 15:34:33 +00005600#ifdef _SC_ABI_ASYNCHRONOUS_IO
5601 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5602#endif
5603#ifdef _SC_ACL
5604 {"SC_ACL", _SC_ACL},
5605#endif
Fred Drakec9680921999-12-13 16:37:25 +00005606#ifdef _SC_AIO_LISTIO_MAX
5607 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5608#endif
Fred Drakec9680921999-12-13 16:37:25 +00005609#ifdef _SC_AIO_MAX
5610 {"SC_AIO_MAX", _SC_AIO_MAX},
5611#endif
5612#ifdef _SC_AIO_PRIO_DELTA_MAX
5613 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5614#endif
5615#ifdef _SC_ARG_MAX
5616 {"SC_ARG_MAX", _SC_ARG_MAX},
5617#endif
5618#ifdef _SC_ASYNCHRONOUS_IO
5619 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5620#endif
5621#ifdef _SC_ATEXIT_MAX
5622 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5623#endif
Fred Draked86ed291999-12-15 15:34:33 +00005624#ifdef _SC_AUDIT
5625 {"SC_AUDIT", _SC_AUDIT},
5626#endif
Fred Drakec9680921999-12-13 16:37:25 +00005627#ifdef _SC_AVPHYS_PAGES
5628 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5629#endif
5630#ifdef _SC_BC_BASE_MAX
5631 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5632#endif
5633#ifdef _SC_BC_DIM_MAX
5634 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5635#endif
5636#ifdef _SC_BC_SCALE_MAX
5637 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5638#endif
5639#ifdef _SC_BC_STRING_MAX
5640 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5641#endif
Fred Draked86ed291999-12-15 15:34:33 +00005642#ifdef _SC_CAP
5643 {"SC_CAP", _SC_CAP},
5644#endif
Fred Drakec9680921999-12-13 16:37:25 +00005645#ifdef _SC_CHARCLASS_NAME_MAX
5646 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5647#endif
5648#ifdef _SC_CHAR_BIT
5649 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5650#endif
5651#ifdef _SC_CHAR_MAX
5652 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5653#endif
5654#ifdef _SC_CHAR_MIN
5655 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5656#endif
5657#ifdef _SC_CHILD_MAX
5658 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5659#endif
5660#ifdef _SC_CLK_TCK
5661 {"SC_CLK_TCK", _SC_CLK_TCK},
5662#endif
5663#ifdef _SC_COHER_BLKSZ
5664 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5665#endif
5666#ifdef _SC_COLL_WEIGHTS_MAX
5667 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5668#endif
5669#ifdef _SC_DCACHE_ASSOC
5670 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5671#endif
5672#ifdef _SC_DCACHE_BLKSZ
5673 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5674#endif
5675#ifdef _SC_DCACHE_LINESZ
5676 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5677#endif
5678#ifdef _SC_DCACHE_SZ
5679 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5680#endif
5681#ifdef _SC_DCACHE_TBLKSZ
5682 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5683#endif
5684#ifdef _SC_DELAYTIMER_MAX
5685 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5686#endif
5687#ifdef _SC_EQUIV_CLASS_MAX
5688 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5689#endif
5690#ifdef _SC_EXPR_NEST_MAX
5691 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5692#endif
5693#ifdef _SC_FSYNC
5694 {"SC_FSYNC", _SC_FSYNC},
5695#endif
5696#ifdef _SC_GETGR_R_SIZE_MAX
5697 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5698#endif
5699#ifdef _SC_GETPW_R_SIZE_MAX
5700 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5701#endif
5702#ifdef _SC_ICACHE_ASSOC
5703 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5704#endif
5705#ifdef _SC_ICACHE_BLKSZ
5706 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5707#endif
5708#ifdef _SC_ICACHE_LINESZ
5709 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5710#endif
5711#ifdef _SC_ICACHE_SZ
5712 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5713#endif
Fred Draked86ed291999-12-15 15:34:33 +00005714#ifdef _SC_INF
5715 {"SC_INF", _SC_INF},
5716#endif
Fred Drakec9680921999-12-13 16:37:25 +00005717#ifdef _SC_INT_MAX
5718 {"SC_INT_MAX", _SC_INT_MAX},
5719#endif
5720#ifdef _SC_INT_MIN
5721 {"SC_INT_MIN", _SC_INT_MIN},
5722#endif
5723#ifdef _SC_IOV_MAX
5724 {"SC_IOV_MAX", _SC_IOV_MAX},
5725#endif
Fred Draked86ed291999-12-15 15:34:33 +00005726#ifdef _SC_IP_SECOPTS
5727 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5728#endif
Fred Drakec9680921999-12-13 16:37:25 +00005729#ifdef _SC_JOB_CONTROL
5730 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5731#endif
Fred Draked86ed291999-12-15 15:34:33 +00005732#ifdef _SC_KERN_POINTERS
5733 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5734#endif
5735#ifdef _SC_KERN_SIM
5736 {"SC_KERN_SIM", _SC_KERN_SIM},
5737#endif
Fred Drakec9680921999-12-13 16:37:25 +00005738#ifdef _SC_LINE_MAX
5739 {"SC_LINE_MAX", _SC_LINE_MAX},
5740#endif
5741#ifdef _SC_LOGIN_NAME_MAX
5742 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5743#endif
5744#ifdef _SC_LOGNAME_MAX
5745 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5746#endif
5747#ifdef _SC_LONG_BIT
5748 {"SC_LONG_BIT", _SC_LONG_BIT},
5749#endif
Fred Draked86ed291999-12-15 15:34:33 +00005750#ifdef _SC_MAC
5751 {"SC_MAC", _SC_MAC},
5752#endif
Fred Drakec9680921999-12-13 16:37:25 +00005753#ifdef _SC_MAPPED_FILES
5754 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5755#endif
5756#ifdef _SC_MAXPID
5757 {"SC_MAXPID", _SC_MAXPID},
5758#endif
5759#ifdef _SC_MB_LEN_MAX
5760 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5761#endif
5762#ifdef _SC_MEMLOCK
5763 {"SC_MEMLOCK", _SC_MEMLOCK},
5764#endif
5765#ifdef _SC_MEMLOCK_RANGE
5766 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5767#endif
5768#ifdef _SC_MEMORY_PROTECTION
5769 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5770#endif
5771#ifdef _SC_MESSAGE_PASSING
5772 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5773#endif
Fred Draked86ed291999-12-15 15:34:33 +00005774#ifdef _SC_MMAP_FIXED_ALIGNMENT
5775 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5776#endif
Fred Drakec9680921999-12-13 16:37:25 +00005777#ifdef _SC_MQ_OPEN_MAX
5778 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5779#endif
5780#ifdef _SC_MQ_PRIO_MAX
5781 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5782#endif
Fred Draked86ed291999-12-15 15:34:33 +00005783#ifdef _SC_NACLS_MAX
5784 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5785#endif
Fred Drakec9680921999-12-13 16:37:25 +00005786#ifdef _SC_NGROUPS_MAX
5787 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5788#endif
5789#ifdef _SC_NL_ARGMAX
5790 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5791#endif
5792#ifdef _SC_NL_LANGMAX
5793 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5794#endif
5795#ifdef _SC_NL_MSGMAX
5796 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5797#endif
5798#ifdef _SC_NL_NMAX
5799 {"SC_NL_NMAX", _SC_NL_NMAX},
5800#endif
5801#ifdef _SC_NL_SETMAX
5802 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5803#endif
5804#ifdef _SC_NL_TEXTMAX
5805 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5806#endif
5807#ifdef _SC_NPROCESSORS_CONF
5808 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5809#endif
5810#ifdef _SC_NPROCESSORS_ONLN
5811 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5812#endif
Fred Draked86ed291999-12-15 15:34:33 +00005813#ifdef _SC_NPROC_CONF
5814 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5815#endif
5816#ifdef _SC_NPROC_ONLN
5817 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5818#endif
Fred Drakec9680921999-12-13 16:37:25 +00005819#ifdef _SC_NZERO
5820 {"SC_NZERO", _SC_NZERO},
5821#endif
5822#ifdef _SC_OPEN_MAX
5823 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5824#endif
5825#ifdef _SC_PAGESIZE
5826 {"SC_PAGESIZE", _SC_PAGESIZE},
5827#endif
5828#ifdef _SC_PAGE_SIZE
5829 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5830#endif
5831#ifdef _SC_PASS_MAX
5832 {"SC_PASS_MAX", _SC_PASS_MAX},
5833#endif
5834#ifdef _SC_PHYS_PAGES
5835 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5836#endif
5837#ifdef _SC_PII
5838 {"SC_PII", _SC_PII},
5839#endif
5840#ifdef _SC_PII_INTERNET
5841 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5842#endif
5843#ifdef _SC_PII_INTERNET_DGRAM
5844 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5845#endif
5846#ifdef _SC_PII_INTERNET_STREAM
5847 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5848#endif
5849#ifdef _SC_PII_OSI
5850 {"SC_PII_OSI", _SC_PII_OSI},
5851#endif
5852#ifdef _SC_PII_OSI_CLTS
5853 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5854#endif
5855#ifdef _SC_PII_OSI_COTS
5856 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5857#endif
5858#ifdef _SC_PII_OSI_M
5859 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5860#endif
5861#ifdef _SC_PII_SOCKET
5862 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5863#endif
5864#ifdef _SC_PII_XTI
5865 {"SC_PII_XTI", _SC_PII_XTI},
5866#endif
5867#ifdef _SC_POLL
5868 {"SC_POLL", _SC_POLL},
5869#endif
5870#ifdef _SC_PRIORITIZED_IO
5871 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5872#endif
5873#ifdef _SC_PRIORITY_SCHEDULING
5874 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5875#endif
5876#ifdef _SC_REALTIME_SIGNALS
5877 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5878#endif
5879#ifdef _SC_RE_DUP_MAX
5880 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5881#endif
5882#ifdef _SC_RTSIG_MAX
5883 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5884#endif
5885#ifdef _SC_SAVED_IDS
5886 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5887#endif
5888#ifdef _SC_SCHAR_MAX
5889 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5890#endif
5891#ifdef _SC_SCHAR_MIN
5892 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5893#endif
5894#ifdef _SC_SELECT
5895 {"SC_SELECT", _SC_SELECT},
5896#endif
5897#ifdef _SC_SEMAPHORES
5898 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5899#endif
5900#ifdef _SC_SEM_NSEMS_MAX
5901 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5902#endif
5903#ifdef _SC_SEM_VALUE_MAX
5904 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5905#endif
5906#ifdef _SC_SHARED_MEMORY_OBJECTS
5907 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5908#endif
5909#ifdef _SC_SHRT_MAX
5910 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5911#endif
5912#ifdef _SC_SHRT_MIN
5913 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5914#endif
5915#ifdef _SC_SIGQUEUE_MAX
5916 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5917#endif
5918#ifdef _SC_SIGRT_MAX
5919 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5920#endif
5921#ifdef _SC_SIGRT_MIN
5922 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5923#endif
Fred Draked86ed291999-12-15 15:34:33 +00005924#ifdef _SC_SOFTPOWER
5925 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5926#endif
Fred Drakec9680921999-12-13 16:37:25 +00005927#ifdef _SC_SPLIT_CACHE
5928 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5929#endif
5930#ifdef _SC_SSIZE_MAX
5931 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5932#endif
5933#ifdef _SC_STACK_PROT
5934 {"SC_STACK_PROT", _SC_STACK_PROT},
5935#endif
5936#ifdef _SC_STREAM_MAX
5937 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5938#endif
5939#ifdef _SC_SYNCHRONIZED_IO
5940 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5941#endif
5942#ifdef _SC_THREADS
5943 {"SC_THREADS", _SC_THREADS},
5944#endif
5945#ifdef _SC_THREAD_ATTR_STACKADDR
5946 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5947#endif
5948#ifdef _SC_THREAD_ATTR_STACKSIZE
5949 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5950#endif
5951#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5952 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5953#endif
5954#ifdef _SC_THREAD_KEYS_MAX
5955 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5956#endif
5957#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5958 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5959#endif
5960#ifdef _SC_THREAD_PRIO_INHERIT
5961 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5962#endif
5963#ifdef _SC_THREAD_PRIO_PROTECT
5964 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5965#endif
5966#ifdef _SC_THREAD_PROCESS_SHARED
5967 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5968#endif
5969#ifdef _SC_THREAD_SAFE_FUNCTIONS
5970 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5971#endif
5972#ifdef _SC_THREAD_STACK_MIN
5973 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5974#endif
5975#ifdef _SC_THREAD_THREADS_MAX
5976 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5977#endif
5978#ifdef _SC_TIMERS
5979 {"SC_TIMERS", _SC_TIMERS},
5980#endif
5981#ifdef _SC_TIMER_MAX
5982 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5983#endif
5984#ifdef _SC_TTY_NAME_MAX
5985 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5986#endif
5987#ifdef _SC_TZNAME_MAX
5988 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5989#endif
5990#ifdef _SC_T_IOV_MAX
5991 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5992#endif
5993#ifdef _SC_UCHAR_MAX
5994 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5995#endif
5996#ifdef _SC_UINT_MAX
5997 {"SC_UINT_MAX", _SC_UINT_MAX},
5998#endif
5999#ifdef _SC_UIO_MAXIOV
6000 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6001#endif
6002#ifdef _SC_ULONG_MAX
6003 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6004#endif
6005#ifdef _SC_USHRT_MAX
6006 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6007#endif
6008#ifdef _SC_VERSION
6009 {"SC_VERSION", _SC_VERSION},
6010#endif
6011#ifdef _SC_WORD_BIT
6012 {"SC_WORD_BIT", _SC_WORD_BIT},
6013#endif
6014#ifdef _SC_XBS5_ILP32_OFF32
6015 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6016#endif
6017#ifdef _SC_XBS5_ILP32_OFFBIG
6018 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6019#endif
6020#ifdef _SC_XBS5_LP64_OFF64
6021 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6022#endif
6023#ifdef _SC_XBS5_LPBIG_OFFBIG
6024 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6025#endif
6026#ifdef _SC_XOPEN_CRYPT
6027 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6028#endif
6029#ifdef _SC_XOPEN_ENH_I18N
6030 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6031#endif
6032#ifdef _SC_XOPEN_LEGACY
6033 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6034#endif
6035#ifdef _SC_XOPEN_REALTIME
6036 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6037#endif
6038#ifdef _SC_XOPEN_REALTIME_THREADS
6039 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6040#endif
6041#ifdef _SC_XOPEN_SHM
6042 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6043#endif
6044#ifdef _SC_XOPEN_UNIX
6045 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6046#endif
6047#ifdef _SC_XOPEN_VERSION
6048 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6049#endif
6050#ifdef _SC_XOPEN_XCU_VERSION
6051 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6052#endif
6053#ifdef _SC_XOPEN_XPG2
6054 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6055#endif
6056#ifdef _SC_XOPEN_XPG3
6057 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6058#endif
6059#ifdef _SC_XOPEN_XPG4
6060 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6061#endif
6062};
6063
6064static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006065conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006066{
6067 return conv_confname(arg, valuep, posix_constants_sysconf,
6068 sizeof(posix_constants_sysconf)
6069 / sizeof(struct constdef));
6070}
6071
6072static char posix_sysconf__doc__[] = "\
6073sysconf(name) -> integer\n\
6074Return an integer-valued system configuration variable.";
6075
6076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006077posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006078{
6079 PyObject *result = NULL;
6080 int name;
6081
6082 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6083 int value;
6084
6085 errno = 0;
6086 value = sysconf(name);
6087 if (value == -1 && errno != 0)
6088 posix_error();
6089 else
6090 result = PyInt_FromLong(value);
6091 }
6092 return result;
6093}
6094#endif
6095
6096
Fred Drakebec628d1999-12-15 18:31:10 +00006097/* This code is used to ensure that the tables of configuration value names
6098 * are in sorted order as required by conv_confname(), and also to build the
6099 * the exported dictionaries that are used to publish information about the
6100 * names available on the host platform.
6101 *
6102 * Sorting the table at runtime ensures that the table is properly ordered
6103 * when used, even for platforms we're not able to test on. It also makes
6104 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006105 */
Fred Drakebec628d1999-12-15 18:31:10 +00006106
6107static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006108cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006109{
6110 const struct constdef *c1 =
6111 (const struct constdef *) v1;
6112 const struct constdef *c2 =
6113 (const struct constdef *) v2;
6114
6115 return strcmp(c1->name, c2->name);
6116}
6117
6118static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006119setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006120 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006121{
Fred Drakebec628d1999-12-15 18:31:10 +00006122 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006123 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006124
6125 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6126 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006127 if (d == NULL)
6128 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006129
Barry Warsaw3155db32000-04-13 15:20:40 +00006130 for (i=0; i < tablesize; ++i) {
6131 PyObject *o = PyInt_FromLong(table[i].value);
6132 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6133 Py_XDECREF(o);
6134 Py_DECREF(d);
6135 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006136 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006137 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006138 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006139 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006140}
6141
Fred Drakebec628d1999-12-15 18:31:10 +00006142/* Return -1 on failure, 0 on success. */
6143static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006144setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006145{
6146#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006147 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006148 sizeof(posix_constants_pathconf)
6149 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006150 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006151 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006152#endif
6153#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006154 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006155 sizeof(posix_constants_confstr)
6156 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006157 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006158 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006159#endif
6160#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006161 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006162 sizeof(posix_constants_sysconf)
6163 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006164 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006165 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006166#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006167 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006168}
Fred Draked86ed291999-12-15 15:34:33 +00006169
6170
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006171static char posix_abort__doc__[] = "\
6172abort() -> does not return!\n\
6173Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
6174in the hardest way possible on the hosting operating system.";
6175
6176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006177posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006178{
6179 if (!PyArg_ParseTuple(args, ":abort"))
6180 return NULL;
6181 abort();
6182 /*NOTREACHED*/
6183 Py_FatalError("abort() called from Python code didn't abort!");
6184 return NULL;
6185}
Fred Drakebec628d1999-12-15 18:31:10 +00006186
Tim Petersf58a7aa2000-09-22 10:05:54 +00006187#ifdef MS_WIN32
6188static char win32_startfile__doc__[] = "\
6189startfile(filepath) - Start a file with its associated application.\n\
6190\n\
6191This acts like double-clicking the file in Explorer, or giving the file\n\
6192name as an argument to the DOS \"start\" command: the file is opened\n\
6193with whatever application (if any) its extension is associated.\n\
6194\n\
6195startfile returns as soon as the associated application is launched.\n\
6196There is no option to wait for the application to close, and no way\n\
6197to retrieve the application's exit status.\n\
6198\n\
6199The filepath is relative to the current directory. If you want to use\n\
6200an absolute path, make sure the first character is not a slash (\"/\");\n\
6201the underlying Win32 ShellExecute function doesn't work if it is.";
6202
6203static PyObject *
6204win32_startfile(PyObject *self, PyObject *args)
6205{
6206 char *filepath;
6207 HINSTANCE rc;
6208 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6209 return NULL;
6210 Py_BEGIN_ALLOW_THREADS
6211 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6212 Py_END_ALLOW_THREADS
6213 if (rc <= (HINSTANCE)32)
6214 return win32_error("startfile", filepath);
6215 Py_INCREF(Py_None);
6216 return Py_None;
6217}
6218#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006219
6220static PyMethodDef posix_methods[] = {
6221 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6222#ifdef HAVE_TTYNAME
6223 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6224#endif
6225 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6226 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006227#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006228 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006229#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006230#ifdef HAVE_CHROOT
6231 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6232#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006233#ifdef HAVE_CTERMID
6234 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6235#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006236#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006237 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006238#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006239#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006240 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006241#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006242 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6243 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6244 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006245#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006246 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006247#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006248#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006249 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006250#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006251 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6252 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6253 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006254#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006255 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006256#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006257#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006258 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006259#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006260 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006261#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006262 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006263#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006264 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6265 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6266 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006267#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006268 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006269#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006270 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006271#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006272 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6273 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006274#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006275#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006276 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6277 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006278#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006279#ifdef HAVE_FORK1
6280 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6281#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006282#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006283 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006284#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006285#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006286 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006287#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006288#ifdef HAVE_FORKPTY
6289 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6290#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006291#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006292 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006293#endif /* HAVE_GETEGID */
6294#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006295 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006296#endif /* HAVE_GETEUID */
6297#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006298 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006299#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006300#ifdef HAVE_GETGROUPS
6301 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6302#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006303 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006304#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006305 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006306#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006307#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006308 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006309#endif /* HAVE_GETPPID */
6310#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006311 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006312#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006313#ifdef HAVE_GETLOGIN
6314 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6315#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006316#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006317 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006318#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006319#ifdef HAVE_KILLPG
6320 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6321#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006322#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006323 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006324#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006325#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006326 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006327#ifdef MS_WIN32
6328 {"popen2", win32_popen2, METH_VARARGS},
6329 {"popen3", win32_popen3, METH_VARARGS},
6330 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006331 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006332#else
6333#if defined(PYOS_OS2) && defined(PYCC_GCC)
6334 {"popen2", os2emx_popen2, METH_VARARGS},
6335 {"popen3", os2emx_popen3, METH_VARARGS},
6336 {"popen4", os2emx_popen4, METH_VARARGS},
6337#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006338#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006339#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006340#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006341 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006342#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006343#ifdef HAVE_SETEUID
6344 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6345#endif /* HAVE_SETEUID */
6346#ifdef HAVE_SETEGID
6347 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6348#endif /* HAVE_SETEGID */
6349#ifdef HAVE_SETREUID
6350 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6351#endif /* HAVE_SETREUID */
6352#ifdef HAVE_SETREGID
6353 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6354#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006355#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006356 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006357#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006358#ifdef HAVE_SETGROUPS
6359 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6360#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006361#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006362 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006363#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006364#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006366#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006367#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006368 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006369#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006370#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006371 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006372#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006373#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006374 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006375#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006376#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006377 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006378#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006379#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006380 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006381#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006382 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6383 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6384 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6385 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6386 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6387 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6388 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6389 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6390 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006391 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006392#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006393 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006394#endif
6395#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006396 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006397#endif
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006398#ifdef HAVE_MKNOD
6399 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6400#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006401#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006402 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006403#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006404#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006405 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006406#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006407#ifdef HAVE_UNSETENV
6408 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6409#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006410#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006411 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006412#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006413#ifdef HAVE_FCHDIR
6414 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6415#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006416#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006417 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006418#endif
6419#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006420 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006421#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006422#ifdef HAVE_SYS_WAIT_H
6423#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006424 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006425#endif /* WIFSTOPPED */
6426#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006427 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006428#endif /* WIFSIGNALED */
6429#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006430 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006431#endif /* WIFEXITED */
6432#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006433 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006434#endif /* WEXITSTATUS */
6435#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006436 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006437#endif /* WTERMSIG */
6438#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006439 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006440#endif /* WSTOPSIG */
6441#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006442#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006443 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006444#endif
6445#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006446 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006447#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006448#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006449 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6450#endif
6451#ifdef HAVE_TEMPNAM
6452 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6453#endif
6454#ifdef HAVE_TMPNAM
6455 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6456#endif
Fred Drakec9680921999-12-13 16:37:25 +00006457#ifdef HAVE_CONFSTR
6458 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6459#endif
6460#ifdef HAVE_SYSCONF
6461 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6462#endif
6463#ifdef HAVE_FPATHCONF
6464 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6465#endif
6466#ifdef HAVE_PATHCONF
6467 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6468#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006469 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00006470#ifdef MS_WIN32
6471 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6472#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006473 {NULL, NULL} /* Sentinel */
6474};
6475
6476
Barry Warsaw4a342091996-12-19 23:50:02 +00006477static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006478ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006479{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006480 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006481}
6482
Guido van Rossumd48f2521997-12-05 22:19:34 +00006483#if defined(PYOS_OS2)
6484/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006485static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006486{
6487 APIRET rc;
6488 ULONG values[QSV_MAX+1];
6489 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006490 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006491
6492 Py_BEGIN_ALLOW_THREADS
6493 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6494 Py_END_ALLOW_THREADS
6495
6496 if (rc != NO_ERROR) {
6497 os2_error(rc);
6498 return -1;
6499 }
6500
Fred Drake4d1e64b2002-04-15 19:40:07 +00006501 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6502 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6503 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6504 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6505 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6506 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6507 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006508
6509 switch (values[QSV_VERSION_MINOR]) {
6510 case 0: ver = "2.00"; break;
6511 case 10: ver = "2.10"; break;
6512 case 11: ver = "2.11"; break;
6513 case 30: ver = "3.00"; break;
6514 case 40: ver = "4.00"; break;
6515 case 50: ver = "5.00"; break;
6516 default:
Tim Peters885d4572001-11-28 20:27:42 +00006517 PyOS_snprintf(tmp, sizeof(tmp),
6518 "%d-%d", values[QSV_VERSION_MAJOR],
6519 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006520 ver = &tmp[0];
6521 }
6522
6523 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006524 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006525 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006526
6527 /* Add Indicator of Which Drive was Used to Boot the System */
6528 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6529 tmp[1] = ':';
6530 tmp[2] = '\0';
6531
Fred Drake4d1e64b2002-04-15 19:40:07 +00006532 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006533}
6534#endif
6535
Barry Warsaw4a342091996-12-19 23:50:02 +00006536static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006537all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006538{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006539#ifdef F_OK
6540 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006541#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006542#ifdef R_OK
6543 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006544#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006545#ifdef W_OK
6546 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006547#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006548#ifdef X_OK
6549 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006550#endif
Fred Drakec9680921999-12-13 16:37:25 +00006551#ifdef NGROUPS_MAX
6552 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6553#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006554#ifdef TMP_MAX
6555 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6556#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006557#ifdef WNOHANG
6558 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006559#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006560#ifdef O_RDONLY
6561 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6562#endif
6563#ifdef O_WRONLY
6564 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6565#endif
6566#ifdef O_RDWR
6567 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6568#endif
6569#ifdef O_NDELAY
6570 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6571#endif
6572#ifdef O_NONBLOCK
6573 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6574#endif
6575#ifdef O_APPEND
6576 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6577#endif
6578#ifdef O_DSYNC
6579 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6580#endif
6581#ifdef O_RSYNC
6582 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6583#endif
6584#ifdef O_SYNC
6585 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6586#endif
6587#ifdef O_NOCTTY
6588 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6589#endif
6590#ifdef O_CREAT
6591 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6592#endif
6593#ifdef O_EXCL
6594 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6595#endif
6596#ifdef O_TRUNC
6597 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6598#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006599#ifdef O_BINARY
6600 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6601#endif
6602#ifdef O_TEXT
6603 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6604#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006605#ifdef O_LARGEFILE
6606 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6607#endif
6608
Tim Peters5aa91602002-01-30 05:46:57 +00006609/* MS Windows */
6610#ifdef O_NOINHERIT
6611 /* Don't inherit in child processes. */
6612 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6613#endif
6614#ifdef _O_SHORT_LIVED
6615 /* Optimize for short life (keep in memory). */
6616 /* MS forgot to define this one with a non-underscore form too. */
6617 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6618#endif
6619#ifdef O_TEMPORARY
6620 /* Automatically delete when last handle is closed. */
6621 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6622#endif
6623#ifdef O_RANDOM
6624 /* Optimize for random access. */
6625 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6626#endif
6627#ifdef O_SEQUENTIAL
6628 /* Optimize for sequential access. */
6629 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6630#endif
6631
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006632/* GNU extensions. */
6633#ifdef O_DIRECT
6634 /* Direct disk access. */
6635 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6636#endif
6637#ifdef O_DIRECTORY
6638 /* Must be a directory. */
6639 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6640#endif
6641#ifdef O_NOFOLLOW
6642 /* Do not follow links. */
6643 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6644#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006645
Guido van Rossum246bc171999-02-01 23:54:31 +00006646#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006647#if defined(PYOS_OS2) && defined(PYCC_GCC)
6648 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6649 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6650 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6651 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6652 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6653 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6654 if (ins(d, "P_PM", (long)P_PM)) return -1;
6655 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6656 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6657 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6658 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6659 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6660 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6661 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6662 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6663 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6664 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6665 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6666 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6667 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6668#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006669 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6670 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6671 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6672 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6673 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006674#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006675#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006676
Guido van Rossumd48f2521997-12-05 22:19:34 +00006677#if defined(PYOS_OS2)
6678 if (insertvalues(d)) return -1;
6679#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006680 return 0;
6681}
6682
6683
Tim Peters5aa91602002-01-30 05:46:57 +00006684#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006685#define INITFUNC initnt
6686#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006687
6688#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006689#define INITFUNC initos2
6690#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006691
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006692#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006693#define INITFUNC initposix
6694#define MODNAME "posix"
6695#endif
6696
Guido van Rossum3886bb61998-12-04 18:50:17 +00006697DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006698INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006699{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006700 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006701
Fred Drake4d1e64b2002-04-15 19:40:07 +00006702 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006703 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006704 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006705
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006706 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006707 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006708 Py_XINCREF(v);
6709 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006710 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006711 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006712
Fred Drake4d1e64b2002-04-15 19:40:07 +00006713 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006714 return;
6715
Fred Drake4d1e64b2002-04-15 19:40:07 +00006716 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006717 return;
6718
Fred Drake4d1e64b2002-04-15 19:40:07 +00006719 Py_INCREF(PyExc_OSError);
6720 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006721
Guido van Rossumb3d39562000-01-31 18:41:26 +00006722#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006723 if (posix_putenv_garbage == NULL)
6724 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006725#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006726
Guido van Rossum14648392001-12-08 18:02:58 +00006727 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006728 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006729 Py_INCREF((PyObject*) &StatResultType);
6730 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006731
Guido van Rossum14648392001-12-08 18:02:58 +00006732 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006733 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006734 Py_INCREF((PyObject*) &StatVFSResultType);
6735 PyModule_AddObject(m, "statvfs_result",
6736 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006737}