blob: 95f4613ac346d5ee34808eff49d5ba2a758d98a7 [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
Neal Norwitz3d949422002-04-20 13:46:43 +0000281#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
282#include <sys/mkdev.h>
283#endif
Fred Drake699f3522000-06-29 21:12:41 +0000284
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285/* Return a dictionary corresponding to the POSIX environment table */
286
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000289#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290
Barry Warsaw53699e91996-12-10 23:23:01 +0000291static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000292convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293{
Barry Warsaw53699e91996-12-10 23:23:01 +0000294 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000296 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 if (d == NULL)
298 return NULL;
299 if (environ == NULL)
300 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000301 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000303 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000304 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000305 char *p = strchr(*e, '=');
306 if (p == NULL)
307 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000308 k = PyString_FromStringAndSize(*e, (int)(p-*e));
309 if (k == NULL) {
310 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000312 }
313 v = PyString_FromString(p+1);
314 if (v == NULL) {
315 PyErr_Clear();
316 Py_DECREF(k);
317 continue;
318 }
319 if (PyDict_GetItem(d, k) == NULL) {
320 if (PyDict_SetItem(d, k, v) != 0)
321 PyErr_Clear();
322 }
323 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000324 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000326#if defined(PYOS_OS2)
327 {
328 APIRET rc;
329 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
330
331 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000332 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000333 PyObject *v = PyString_FromString(buffer);
334 PyDict_SetItemString(d, "BEGINLIBPATH", v);
335 Py_DECREF(v);
336 }
337 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
338 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
339 PyObject *v = PyString_FromString(buffer);
340 PyDict_SetItemString(d, "ENDLIBPATH", v);
341 Py_DECREF(v);
342 }
343 }
344#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 return d;
346}
347
348
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349/* Set a POSIX-specific error from errno, and return NULL */
350
Barry Warsawd58d7641998-07-23 16:14:40 +0000351static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000352posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000353{
Barry Warsawca74da41999-02-09 19:31:45 +0000354 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000355}
Barry Warsawd58d7641998-07-23 16:14:40 +0000356static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000357posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000358{
Barry Warsawca74da41999-02-09 19:31:45 +0000359 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000360}
361
Mark Hammondef8b6542001-05-13 08:04:26 +0000362static PyObject *
363posix_error_with_allocated_filename(char* name)
364{
365 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
366 PyMem_Free(name);
367 return rc;
368}
369
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000370#ifdef MS_WIN32
371static PyObject *
372win32_error(char* function, char* filename)
373{
Mark Hammond33a6da92000-08-15 00:46:38 +0000374 /* XXX We should pass the function name along in the future.
375 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000376 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000377 Windows error object, which is non-trivial.
378 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000379 errno = GetLastError();
380 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000381 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000382 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000383 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000384}
385#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000386
Guido van Rossumd48f2521997-12-05 22:19:34 +0000387#if defined(PYOS_OS2)
388/**********************************************************************
389 * Helper Function to Trim and Format OS/2 Messages
390 **********************************************************************/
391 static void
392os2_formatmsg(char *msgbuf, int msglen, char *reason)
393{
394 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
395
396 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
397 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
398
399 while (lastc > msgbuf && isspace(*lastc))
400 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
401 }
402
403 /* Add Optional Reason Text */
404 if (reason) {
405 strcat(msgbuf, " : ");
406 strcat(msgbuf, reason);
407 }
408}
409
410/**********************************************************************
411 * Decode an OS/2 Operating System Error Code
412 *
413 * A convenience function to lookup an OS/2 error code and return a
414 * text message we can use to raise a Python exception.
415 *
416 * Notes:
417 * The messages for errors returned from the OS/2 kernel reside in
418 * the file OSO001.MSG in the \OS2 directory hierarchy.
419 *
420 **********************************************************************/
421 static char *
422os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
423{
424 APIRET rc;
425 ULONG msglen;
426
427 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
428 Py_BEGIN_ALLOW_THREADS
429 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
430 errorcode, "oso001.msg", &msglen);
431 Py_END_ALLOW_THREADS
432
433 if (rc == NO_ERROR)
434 os2_formatmsg(msgbuf, msglen, reason);
435 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000436 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000437 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000438
439 return msgbuf;
440}
441
442/* Set an OS/2-specific error and return NULL. OS/2 kernel
443 errors are not in a global variable e.g. 'errno' nor are
444 they congruent with posix error numbers. */
445
446static PyObject * os2_error(int code)
447{
448 char text[1024];
449 PyObject *v;
450
451 os2_strerror(text, sizeof(text), code, "");
452
453 v = Py_BuildValue("(is)", code, text);
454 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000455 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000456 Py_DECREF(v);
457 }
458 return NULL; /* Signal to Python that an Exception is Pending */
459}
460
461#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000462
463/* POSIX generic methods */
464
Barry Warsaw53699e91996-12-10 23:23:01 +0000465static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000466posix_fildes(PyObject *fdobj, int (*func)(int))
467{
468 int fd;
469 int res;
470 fd = PyObject_AsFileDescriptor(fdobj);
471 if (fd < 0)
472 return NULL;
473 Py_BEGIN_ALLOW_THREADS
474 res = (*func)(fd);
475 Py_END_ALLOW_THREADS
476 if (res < 0)
477 return posix_error();
478 Py_INCREF(Py_None);
479 return Py_None;
480}
Guido van Rossum21142a01999-01-08 21:05:37 +0000481
482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000483posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000484{
Mark Hammondef8b6542001-05-13 08:04:26 +0000485 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000486 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000487 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000488 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000490 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000491 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000492 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000493 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000494 return posix_error_with_allocated_filename(path1);
495 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000496 Py_INCREF(Py_None);
497 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000498}
499
Barry Warsaw53699e91996-12-10 23:23:01 +0000500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000501posix_2str(PyObject *args, char *format,
502 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000503{
Mark Hammondef8b6542001-05-13 08:04:26 +0000504 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000505 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000506 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000507 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000508 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000510 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000511 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000512 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000513 PyMem_Free(path1);
514 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000515 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000516 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000518 Py_INCREF(Py_None);
519 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000520}
521
Tim Peters5aa91602002-01-30 05:46:57 +0000522static char stat_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000523"stat_result: Result from stat or lstat.\n\n\
524This object may be accessed either as a tuple of\n\
525 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
526or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
527\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000528Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000529they are available as attributes only.\n\
530\n\
531See os.stat for more information.\n";
532
533static PyStructSequence_Field stat_result_fields[] = {
534 {"st_mode", "protection bits"},
535 {"st_ino", "inode"},
536 {"st_dev", "device"},
537 {"st_nlink", "number of hard links"},
538 {"st_uid", "user ID of owner"},
539 {"st_gid", "group ID of owner"},
540 {"st_size", "total size, in bytes"},
541 {"st_atime", "time of last access"},
542 {"st_mtime", "time of last modification"},
543 {"st_ctime", "time of last change"},
544#ifdef HAVE_ST_BLKSIZE
545 {"st_blksize", "blocksize for filesystem I/O"},
546#endif
547#ifdef HAVE_ST_BLOCKS
548 {"st_blocks", "number of blocks allocated"},
549#endif
550#ifdef HAVE_ST_RDEV
551 {"st_rdev", "device type (if inode device)"},
552#endif
553 {0}
554};
555
556#ifdef HAVE_ST_BLKSIZE
557#define ST_BLKSIZE_IDX 10
558#else
559#define ST_BLKSIZE_IDX 9
560#endif
561
562#ifdef HAVE_ST_BLOCKS
563#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
564#else
565#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
566#endif
567
568#ifdef HAVE_ST_RDEV
569#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
570#else
571#define ST_RDEV_IDX ST_BLOCKS_IDX
572#endif
573
574static PyStructSequence_Desc stat_result_desc = {
575 "stat_result", /* name */
576 stat_result__doc__, /* doc */
577 stat_result_fields,
578 10
579};
580
Tim Peters5aa91602002-01-30 05:46:57 +0000581static char statvfs_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000582"statvfs_result: Result from statvfs or fstatvfs.\n\n\
583This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000584 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
585or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000586\n\
587See os.statvfs for more information.\n";
588
589static PyStructSequence_Field statvfs_result_fields[] = {
590 {"f_bsize", },
591 {"f_frsize", },
592 {"f_blocks", },
593 {"f_bfree", },
594 {"f_bavail", },
595 {"f_files", },
596 {"f_ffree", },
597 {"f_favail", },
598 {"f_flag", },
599 {"f_namemax",},
600 {0}
601};
602
603static PyStructSequence_Desc statvfs_result_desc = {
604 "statvfs_result", /* name */
605 statvfs_result__doc__, /* doc */
606 statvfs_result_fields,
607 10
608};
609
610static PyTypeObject StatResultType;
611static PyTypeObject StatVFSResultType;
612
Tim Peters5aa91602002-01-30 05:46:57 +0000613/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000614 (used by posix_stat() and posix_fstat()) */
615static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000616_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000617{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000618 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000619 if (v == NULL)
620 return NULL;
621
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000622 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000623#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000624 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000625 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000626#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000627 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000628#endif
629#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000630 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000631 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000632#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000633 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000634#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000635 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
636 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
637 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000638#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000639 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000640 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000641#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000642 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000643#endif
644#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000645 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000646 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000647 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000648 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000649 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000650 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000651#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000652 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
653 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
654 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
655#endif
656
657#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000658 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000659 PyInt_FromLong((long)st.st_blksize));
660#endif
661#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000662 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000663 PyInt_FromLong((long)st.st_blocks));
664#endif
665#ifdef HAVE_ST_RDEV
666 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
667 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000668#endif
669
670 if (PyErr_Occurred()) {
671 Py_DECREF(v);
672 return NULL;
673 }
674
675 return v;
676}
677
Barry Warsaw53699e91996-12-10 23:23:01 +0000678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000679posix_do_stat(PyObject *self, PyObject *args, char *format,
680 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681{
Fred Drake699f3522000-06-29 21:12:41 +0000682 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000683 char *path = NULL; /* pass this to stat; do not free() it */
684 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000685 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000686
687#ifdef MS_WIN32
Tim Peters500bd032001-12-19 19:05:01 +0000688 int pathlen;
689 char pathcopy[MAX_PATH];
Guido van Rossumace88ae2000-04-21 18:54:45 +0000690#endif /* MS_WIN32 */
691
Tim Peters5aa91602002-01-30 05:46:57 +0000692 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000693 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000695 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000696
697#ifdef MS_WIN32
698 pathlen = strlen(path);
699 /* the library call can blow up if the file name is too long! */
700 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000701 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000702 errno = ENAMETOOLONG;
703 return posix_error();
704 }
705
Tim Peters500bd032001-12-19 19:05:01 +0000706 /* Remove trailing slash or backslash, unless it's the current
707 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
708 */
709 if (pathlen > 0 &&
710 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
711 /* It does end with a slash -- exempt the root drive cases. */
712 /* XXX UNC root drives should also be exempted? */
713 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
714 /* leave it alone */;
715 else {
716 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000717 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000718 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000719 path = pathcopy;
720 }
721 }
722#endif /* MS_WIN32 */
723
Barry Warsaw53699e91996-12-10 23:23:01 +0000724 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000725 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000726 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000727 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000728 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000729
Tim Peters500bd032001-12-19 19:05:01 +0000730 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000731 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000732}
733
734
735/* POSIX methods */
736
Guido van Rossum94f6f721999-01-06 18:42:14 +0000737static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000738"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000739Test for access to a file.";
740
741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000742posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000743{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000744 char *path;
745 int mode;
746 int res;
747
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000748 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000749 return NULL;
750 Py_BEGIN_ALLOW_THREADS
751 res = access(path, mode);
752 Py_END_ALLOW_THREADS
753 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000754}
755
Guido van Rossumd371ff11999-01-25 16:12:23 +0000756#ifndef F_OK
757#define F_OK 0
758#endif
759#ifndef R_OK
760#define R_OK 4
761#endif
762#ifndef W_OK
763#define W_OK 2
764#endif
765#ifndef X_OK
766#define X_OK 1
767#endif
768
769#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000770static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000771"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000772Return the name of the terminal device connected to 'fd'.";
773
774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000775posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000776{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000777 int id;
778 char *ret;
779
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000780 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000781 return NULL;
782
Guido van Rossum94f6f721999-01-06 18:42:14 +0000783 ret = ttyname(id);
784 if (ret == NULL)
785 return(posix_error());
786 return(PyString_FromString(ret));
787}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000788#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000789
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000790#ifdef HAVE_CTERMID
791static char posix_ctermid__doc__[] =
792"ctermid() -> String\n\
793Return the name of the controlling terminal for this process.";
794
795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000796posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000797{
798 char *ret;
799 char buffer[L_ctermid];
800
801 if (!PyArg_ParseTuple(args, ":ctermid"))
802 return NULL;
803
Greg Wardb48bc172000-03-01 21:51:56 +0000804#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000805 ret = ctermid_r(buffer);
806#else
807 ret = ctermid(buffer);
808#endif
809 if (ret == NULL)
810 return(posix_error());
811 return(PyString_FromString(buffer));
812}
813#endif
814
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000815static char posix_chdir__doc__[] =
816"chdir(path) -> None\n\
817Change the current working directory to the specified path.";
818
Barry Warsaw53699e91996-12-10 23:23:01 +0000819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000820posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000821{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000822#if defined(PYOS_OS2) && defined(PYCC_GCC)
823 return posix_1str(args, "et:chdir", _chdir2);
824#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000825 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000826#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000827}
828
Fred Drake4d1e64b2002-04-15 19:40:07 +0000829#ifdef HAVE_FCHDIR
830static char posix_fchdir__doc__[] =
831"fchdir(fildes) -> None\n\
832Change to the directory of the given file descriptor. fildes must be\n\
833opened on a directory, not a file.";
834
835static PyObject *
836posix_fchdir(PyObject *self, PyObject *fdobj)
837{
838 return posix_fildes(fdobj, fchdir);
839}
840#endif /* HAVE_FCHDIR */
841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000842
843static char posix_chmod__doc__[] =
844"chmod(path, mode) -> None\n\
845Change the access permissions of a file.";
846
Barry Warsaw53699e91996-12-10 23:23:01 +0000847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000848posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000849{
Mark Hammondef8b6542001-05-13 08:04:26 +0000850 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000851 int i;
852 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000853 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000854 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000855 return NULL;
856 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000857 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000858 Py_END_ALLOW_THREADS
859 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000860 return posix_error_with_allocated_filename(path);
861 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000862 Py_INCREF(Py_None);
863 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000864}
865
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000866
Martin v. Löwis244edc82001-10-04 22:44:26 +0000867#ifdef HAVE_CHROOT
Tim Peters5aa91602002-01-30 05:46:57 +0000868static char posix_chroot__doc__[] =
Martin v. Löwis244edc82001-10-04 22:44:26 +0000869"chroot(path) -> None\n\
870Change root directory to path.";
871
872static PyObject *
873posix_chroot(PyObject *self, PyObject *args)
874{
875 return posix_1str(args, "et:chroot", chroot);
876}
877#endif
878
Guido van Rossum21142a01999-01-08 21:05:37 +0000879#ifdef HAVE_FSYNC
880static char posix_fsync__doc__[] =
881"fsync(fildes) -> None\n\
882force write of file with filedescriptor to disk.";
883
884static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000885posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000886{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000887 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000888}
889#endif /* HAVE_FSYNC */
890
891#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000892
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000893#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000894extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
895#endif
896
Guido van Rossum21142a01999-01-08 21:05:37 +0000897static char posix_fdatasync__doc__[] =
898"fdatasync(fildes) -> None\n\
899force write of file with filedescriptor to disk.\n\
900 does not force update of metadata.";
901
902static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000903posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000904{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000905 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000906}
907#endif /* HAVE_FDATASYNC */
908
909
Fredrik Lundh10723342000-07-10 16:38:09 +0000910#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000911static char posix_chown__doc__[] =
912"chown(path, uid, gid) -> None\n\
913Change the owner and group id of path to the numeric uid and gid.";
914
Barry Warsaw53699e91996-12-10 23:23:01 +0000915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000916posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000917{
Mark Hammondef8b6542001-05-13 08:04:26 +0000918 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000919 int uid, gid;
920 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000921 if (!PyArg_ParseTuple(args, "etii:chown",
922 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000923 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000924 return NULL;
925 Py_BEGIN_ALLOW_THREADS
926 res = chown(path, (uid_t) uid, (gid_t) gid);
927 Py_END_ALLOW_THREADS
928 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000929 return posix_error_with_allocated_filename(path);
930 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000931 Py_INCREF(Py_None);
932 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000933}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000934#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000935
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000936
Guido van Rossum36bc6801995-06-14 22:54:23 +0000937#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000938static char posix_getcwd__doc__[] =
939"getcwd() -> path\n\
940Return a string representing the current working directory.";
941
Barry Warsaw53699e91996-12-10 23:23:01 +0000942static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000943posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000944{
945 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000946 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000947 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000948 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000949 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000950#if defined(PYOS_OS2) && defined(PYCC_GCC)
951 res = _getcwd2(buf, sizeof buf);
952#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000953 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000954#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000955 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000956 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000957 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000958 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000959}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000960#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000961
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000962
Guido van Rossumb6775db1994-08-01 11:34:53 +0000963#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000964static char posix_link__doc__[] =
965"link(src, dst) -> None\n\
966Create a hard link to a file.";
967
Barry Warsaw53699e91996-12-10 23:23:01 +0000968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000969posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000970{
Mark Hammondef8b6542001-05-13 08:04:26 +0000971 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000972}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000973#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000975
976static char posix_listdir__doc__[] =
977"listdir(path) -> list_of_strings\n\
978Return a list containing the names of the entries in the directory.\n\
979\n\
980 path: path of directory to list\n\
981\n\
982The list is in arbitrary order. It does not include the special\n\
983entries '.' and '..' even if they are present in the directory.";
984
Barry Warsaw53699e91996-12-10 23:23:01 +0000985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000986posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000987{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000988 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000989 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000990#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000991
Barry Warsaw53699e91996-12-10 23:23:01 +0000992 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000993 HANDLE hFindFile;
994 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000995 /* MAX_PATH characters could mean a bigger encoded string */
996 char namebuf[MAX_PATH*2+5];
997 char *bufptr = namebuf;
998 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000999
Tim Peters5aa91602002-01-30 05:46:57 +00001000 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001001 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001002 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001003 if (len > 0) {
1004 char ch = namebuf[len-1];
1005 if (ch != SEP && ch != ALTSEP && ch != ':')
1006 namebuf[len++] = '/';
1007 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001008 strcpy(namebuf + len, "*.*");
1009
Barry Warsaw53699e91996-12-10 23:23:01 +00001010 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001011 return NULL;
1012
1013 hFindFile = FindFirstFile(namebuf, &FileData);
1014 if (hFindFile == INVALID_HANDLE_VALUE) {
1015 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001016 if (errno == ERROR_FILE_NOT_FOUND)
1017 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001018 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001019 }
1020 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001021 if (FileData.cFileName[0] == '.' &&
1022 (FileData.cFileName[1] == '\0' ||
1023 FileData.cFileName[1] == '.' &&
1024 FileData.cFileName[2] == '\0'))
1025 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001026 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001027 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001028 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001029 d = NULL;
1030 break;
1031 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001032 if (PyList_Append(d, v) != 0) {
1033 Py_DECREF(v);
1034 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001035 d = NULL;
1036 break;
1037 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001038 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001039 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1040
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001041 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001042 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001043
1044 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001045
Tim Peters0bb44a42000-09-15 07:44:49 +00001046#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001047
1048#ifndef MAX_PATH
1049#define MAX_PATH 250
1050#endif
1051 char *name, *pt;
1052 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001053 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001054 char namebuf[MAX_PATH+5];
1055 struct _find_t ep;
1056
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001057 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001058 return NULL;
1059 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001060 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001061 return NULL;
1062 }
1063 strcpy(namebuf, name);
1064 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001065 if (*pt == ALTSEP)
1066 *pt = SEP;
1067 if (namebuf[len-1] != SEP)
1068 namebuf[len++] = SEP;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001069 strcpy(namebuf + len, "*.*");
1070
Barry Warsaw53699e91996-12-10 23:23:01 +00001071 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001072 return NULL;
1073
1074 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001075 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1076 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001077 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001078 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001079 }
1080 do {
1081 if (ep.name[0] == '.' &&
1082 (ep.name[1] == '\0' ||
1083 ep.name[1] == '.' &&
1084 ep.name[2] == '\0'))
1085 continue;
1086 strcpy(namebuf, ep.name);
1087 for (pt = namebuf; *pt; pt++)
1088 if (isupper(*pt))
1089 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001090 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001091 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001092 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001093 d = NULL;
1094 break;
1095 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001096 if (PyList_Append(d, v) != 0) {
1097 Py_DECREF(v);
1098 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001099 d = NULL;
1100 break;
1101 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001102 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001103 } while (_dos_findnext(&ep) == 0);
1104
1105 return d;
1106
Tim Peters0bb44a42000-09-15 07:44:49 +00001107#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001108
1109#ifndef MAX_PATH
1110#define MAX_PATH CCHMAXPATH
1111#endif
1112 char *name, *pt;
1113 int len;
1114 PyObject *d, *v;
1115 char namebuf[MAX_PATH+5];
1116 HDIR hdir = 1;
1117 ULONG srchcnt = 1;
1118 FILEFINDBUF3 ep;
1119 APIRET rc;
1120
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001121 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001122 return NULL;
1123 if (len >= MAX_PATH) {
1124 PyErr_SetString(PyExc_ValueError, "path too long");
1125 return NULL;
1126 }
1127 strcpy(namebuf, name);
1128 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001129 if (*pt == ALTSEP)
1130 *pt = SEP;
1131 if (namebuf[len-1] != SEP)
1132 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001133 strcpy(namebuf + len, "*.*");
1134
1135 if ((d = PyList_New(0)) == NULL)
1136 return NULL;
1137
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001138 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1139 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001140 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001141 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1142 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1143 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001144
1145 if (rc != NO_ERROR) {
1146 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001147 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001148 }
1149
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001150 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001151 do {
1152 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001153 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001154 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001155
1156 strcpy(namebuf, ep.achName);
1157
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001158 /* Leave Case of Name Alone -- In Native Form */
1159 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001160
1161 v = PyString_FromString(namebuf);
1162 if (v == NULL) {
1163 Py_DECREF(d);
1164 d = NULL;
1165 break;
1166 }
1167 if (PyList_Append(d, v) != 0) {
1168 Py_DECREF(v);
1169 Py_DECREF(d);
1170 d = NULL;
1171 break;
1172 }
1173 Py_DECREF(v);
1174 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1175 }
1176
1177 return d;
1178#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001179
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001180 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001181 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001183 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001184 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001186 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001187 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001188 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001189 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001190 closedir(dirp);
1191 return NULL;
1192 }
1193 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001194 if (ep->d_name[0] == '.' &&
1195 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001196 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001197 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001198 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001199 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001200 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001201 d = NULL;
1202 break;
1203 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001204 if (PyList_Append(d, v) != 0) {
1205 Py_DECREF(v);
1206 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001207 d = NULL;
1208 break;
1209 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001210 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211 }
1212 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001213
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001215
Tim Peters0bb44a42000-09-15 07:44:49 +00001216#endif /* which OS */
1217} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218
Mark Hammondef8b6542001-05-13 08:04:26 +00001219#ifdef MS_WIN32
1220/* A helper function for abspath on win32 */
1221static PyObject *
1222posix__getfullpathname(PyObject *self, PyObject *args)
1223{
1224 /* assume encoded strings wont more than double no of chars */
1225 char inbuf[MAX_PATH*2];
1226 char *inbufp = inbuf;
1227 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1228 char outbuf[MAX_PATH*2];
1229 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001230 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1231 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001232 &insize))
1233 return NULL;
1234 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1235 outbuf, &temp))
1236 return win32_error("GetFullPathName", inbuf);
1237 return PyString_FromString(outbuf);
1238} /* end of posix__getfullpathname */
1239#endif /* MS_WIN32 */
1240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001241static char posix_mkdir__doc__[] =
1242"mkdir(path [, mode=0777]) -> None\n\
1243Create a directory.";
1244
Barry Warsaw53699e91996-12-10 23:23:01 +00001245static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001246posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001247{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001248 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001249 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001250 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001251 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001252 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001253 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001254 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001255#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001256 res = mkdir(path);
1257#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001258 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001259#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001260 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001261 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001262 return posix_error_with_allocated_filename(path);
1263 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001264 Py_INCREF(Py_None);
1265 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001266}
1267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001268
Guido van Rossumb6775db1994-08-01 11:34:53 +00001269#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001270#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1271#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1272#include <sys/resource.h>
1273#endif
1274#endif
1275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001276static char posix_nice__doc__[] =
1277"nice(inc) -> new_priority\n\
1278Decrease the priority of process and return new priority.";
1279
Barry Warsaw53699e91996-12-10 23:23:01 +00001280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001281posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001282{
1283 int increment, value;
1284
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001285 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001286 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001287
1288 /* There are two flavours of 'nice': one that returns the new
1289 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001290 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1291 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001292
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001293 If we are of the nice family that returns the new priority, we
1294 need to clear errno before the call, and check if errno is filled
1295 before calling posix_error() on a returnvalue of -1, because the
1296 -1 may be the actual new priority! */
1297
1298 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001299 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001300#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001301 if (value == 0)
1302 value = getpriority(PRIO_PROCESS, 0);
1303#endif
1304 if (value == -1 && errno != 0)
1305 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001306 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001307 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001308}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001309#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001311
1312static char posix_rename__doc__[] =
1313"rename(old, new) -> None\n\
1314Rename a file or directory.";
1315
Barry Warsaw53699e91996-12-10 23:23:01 +00001316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001317posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001318{
Mark Hammondef8b6542001-05-13 08:04:26 +00001319 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001320}
1321
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001322
1323static char posix_rmdir__doc__[] =
1324"rmdir(path) -> None\n\
1325Remove a directory.";
1326
Barry Warsaw53699e91996-12-10 23:23:01 +00001327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001328posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001329{
Mark Hammondef8b6542001-05-13 08:04:26 +00001330 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331}
1332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001333
1334static char posix_stat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00001335"stat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
1336 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001337Perform a stat system call on the given path.";
1338
Barry Warsaw53699e91996-12-10 23:23:01 +00001339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001340posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341{
Mark Hammondef8b6542001-05-13 08:04:26 +00001342 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001343}
1344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001345
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001346#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001347static char posix_system__doc__[] =
1348"system(command) -> exit_status\n\
1349Execute the command (a string) in a subshell.";
1350
Barry Warsaw53699e91996-12-10 23:23:01 +00001351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001352posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001353{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001354 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001355 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001356 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001358 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001359 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001360 Py_END_ALLOW_THREADS
1361 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001363#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001365
1366static char posix_umask__doc__[] =
1367"umask(new_mask) -> old_mask\n\
1368Set the current numeric umask and return the previous umask.";
1369
Barry Warsaw53699e91996-12-10 23:23:01 +00001370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001371posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001372{
1373 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001374 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001375 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001376 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001377 if (i < 0)
1378 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001379 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001380}
1381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001382
1383static char posix_unlink__doc__[] =
1384"unlink(path) -> None\n\
1385Remove a file (same as remove(path)).";
1386
1387static char posix_remove__doc__[] =
1388"remove(path) -> None\n\
1389Remove a file (same as unlink(path)).";
1390
Barry Warsaw53699e91996-12-10 23:23:01 +00001391static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001392posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393{
Mark Hammondef8b6542001-05-13 08:04:26 +00001394 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001395}
1396
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001397
Guido van Rossumb6775db1994-08-01 11:34:53 +00001398#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001399static char posix_uname__doc__[] =
1400"uname() -> (sysname, nodename, release, version, machine)\n\
1401Return a tuple identifying the current operating system.";
1402
Barry Warsaw53699e91996-12-10 23:23:01 +00001403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001404posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001405{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001406 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001407 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001408 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001409 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001410 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001411 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001412 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001413 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001414 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001415 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001416 u.sysname,
1417 u.nodename,
1418 u.release,
1419 u.version,
1420 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001421}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001422#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001423
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001424
1425static char posix_utime__doc__[] =
1426"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001427utime(path, None) -> None\n\
1428Set the access and modified time of the file to the given values. If the\n\
1429second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001430
Barry Warsaw53699e91996-12-10 23:23:01 +00001431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001432posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001433{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001434 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001435 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001436 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001437 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001438
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001439/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001440#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001441 struct utimbuf buf;
1442#define ATIME buf.actime
1443#define MTIME buf.modtime
1444#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001445#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001446 time_t buf[2];
1447#define ATIME buf[0]
1448#define MTIME buf[1]
1449#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001450#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001451
Barry Warsaw3cef8562000-05-01 16:17:24 +00001452 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001453 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001454 if (arg == Py_None) {
1455 /* optional time values not given */
1456 Py_BEGIN_ALLOW_THREADS
1457 res = utime(path, NULL);
1458 Py_END_ALLOW_THREADS
1459 }
1460 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1461 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001462 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001463 return NULL;
1464 }
1465 else {
1466 ATIME = atime;
1467 MTIME = mtime;
1468 Py_BEGIN_ALLOW_THREADS
1469 res = utime(path, UTIME_ARG);
1470 Py_END_ALLOW_THREADS
1471 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001472 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001473 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001474 Py_INCREF(Py_None);
1475 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001476#undef UTIME_ARG
1477#undef ATIME
1478#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001479}
1480
Guido van Rossum85e3b011991-06-03 12:42:10 +00001481
Guido van Rossum3b066191991-06-04 19:40:25 +00001482/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001483
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001484static char posix__exit__doc__[] =
1485"_exit(status)\n\
1486Exit to the system with specified status, without normal exit processing.";
1487
Barry Warsaw53699e91996-12-10 23:23:01 +00001488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001489posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001490{
1491 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001492 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001493 return NULL;
1494 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001495 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001496}
1497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001498
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001499#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001500static char posix_execv__doc__[] =
1501"execv(path, args)\n\
1502Execute an executable path with arguments, replacing current process.\n\
1503\n\
1504 path: path of executable file\n\
1505 args: tuple or list of strings";
1506
Barry Warsaw53699e91996-12-10 23:23:01 +00001507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001508posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001509{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001510 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001511 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001512 char **argvlist;
1513 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001514 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001515
Guido van Rossum89b33251993-10-22 14:26:06 +00001516 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001517 argv is a list or tuple of strings. */
1518
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001519 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001520 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001521 if (PyList_Check(argv)) {
1522 argc = PyList_Size(argv);
1523 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001524 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001525 else if (PyTuple_Check(argv)) {
1526 argc = PyTuple_Size(argv);
1527 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001528 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001529 else {
Fred Drake661ea262000-10-24 19:57:45 +00001530 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001531 return NULL;
1532 }
1533
1534 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001535 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001536 return NULL;
1537 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001538
Barry Warsaw53699e91996-12-10 23:23:01 +00001539 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001540 if (argvlist == NULL)
1541 return NULL;
1542 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001543 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1544 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001545 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001546 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001547 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001548
Guido van Rossum85e3b011991-06-03 12:42:10 +00001549 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001550 }
1551 argvlist[argc] = NULL;
1552
Guido van Rossumb6775db1994-08-01 11:34:53 +00001553#ifdef BAD_EXEC_PROTOTYPES
1554 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001555#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001556 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001557#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001558
Guido van Rossum85e3b011991-06-03 12:42:10 +00001559 /* If we get here it's definitely an error */
1560
Barry Warsaw53699e91996-12-10 23:23:01 +00001561 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001562 return posix_error();
1563}
1564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001565
1566static char posix_execve__doc__[] =
1567"execve(path, args, env)\n\
1568Execute a path with arguments and environment, replacing current process.\n\
1569\n\
1570 path: path of executable file\n\
1571 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001572 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001573
Barry Warsaw53699e91996-12-10 23:23:01 +00001574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001575posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001576{
1577 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001578 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001579 char **argvlist;
1580 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001581 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001582 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001583 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001584
1585 /* execve has three arguments: (path, argv, env), where
1586 argv is a list or tuple of strings and env is a dictionary
1587 like posix.environ. */
1588
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001589 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001590 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001591 if (PyList_Check(argv)) {
1592 argc = PyList_Size(argv);
1593 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001594 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001595 else if (PyTuple_Check(argv)) {
1596 argc = PyTuple_Size(argv);
1597 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001598 }
1599 else {
Fred Drake661ea262000-10-24 19:57:45 +00001600 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 return NULL;
1602 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001603 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001604 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001605 return NULL;
1606 }
1607
Guido van Rossum50422b42000-04-26 20:34:28 +00001608 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001609 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001610 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001611 return NULL;
1612 }
1613
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001615 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001616 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001617 return NULL;
1618 }
1619 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001620 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001621 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001622 &argvlist[i]))
1623 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001624 goto fail_1;
1625 }
1626 }
1627 argvlist[argc] = NULL;
1628
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001629 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001630 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001631 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001632 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001633 goto fail_1;
1634 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001635 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001636 keys = PyMapping_Keys(env);
1637 vals = PyMapping_Values(env);
1638 if (!keys || !vals)
1639 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001640
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001641 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001642 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001643 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001644
1645 key = PyList_GetItem(keys, pos);
1646 val = PyList_GetItem(vals, pos);
1647 if (!key || !val)
1648 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001649
Fred Drake661ea262000-10-24 19:57:45 +00001650 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1651 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001652 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001653 goto fail_2;
1654 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001655
1656#if defined(PYOS_OS2)
1657 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1658 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1659#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001660 len = PyString_Size(key) + PyString_Size(val) + 2;
1661 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001662 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001663 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001664 goto fail_2;
1665 }
Tim Petersc8996f52001-12-03 20:41:00 +00001666 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001667 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001668#if defined(PYOS_OS2)
1669 }
1670#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001671 }
1672 envlist[envc] = 0;
1673
Guido van Rossumb6775db1994-08-01 11:34:53 +00001674
1675#ifdef BAD_EXEC_PROTOTYPES
1676 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001677#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001678 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001679#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001680
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001681 /* If we get here it's definitely an error */
1682
1683 (void) posix_error();
1684
1685 fail_2:
1686 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001687 PyMem_DEL(envlist[envc]);
1688 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001689 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001690 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001691 Py_XDECREF(vals);
1692 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001693 return NULL;
1694}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001695#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001696
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001697
Guido van Rossuma1065681999-01-25 23:20:23 +00001698#ifdef HAVE_SPAWNV
1699static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001700"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001701Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001702\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001703 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001704 path: path of executable file\n\
1705 args: tuple or list of strings";
1706
1707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001708posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001709{
1710 char *path;
1711 PyObject *argv;
1712 char **argvlist;
1713 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001714 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001715 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001716
1717 /* spawnv has three arguments: (mode, path, argv), where
1718 argv is a list or tuple of strings. */
1719
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001720 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001721 return NULL;
1722 if (PyList_Check(argv)) {
1723 argc = PyList_Size(argv);
1724 getitem = PyList_GetItem;
1725 }
1726 else if (PyTuple_Check(argv)) {
1727 argc = PyTuple_Size(argv);
1728 getitem = PyTuple_GetItem;
1729 }
1730 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001731 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001732 return NULL;
1733 }
1734
1735 argvlist = PyMem_NEW(char *, argc+1);
1736 if (argvlist == NULL)
1737 return NULL;
1738 for (i = 0; i < argc; i++) {
1739 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1740 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001741 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001742 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001743 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001744 }
1745 }
1746 argvlist[argc] = NULL;
1747
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001748#if defined(PYOS_OS2) && defined(PYCC_GCC)
1749 Py_BEGIN_ALLOW_THREADS
1750 spawnval = spawnv(mode, path, argvlist);
1751 Py_END_ALLOW_THREADS
1752#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001753 if (mode == _OLD_P_OVERLAY)
1754 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001755
Tim Peters25059d32001-12-07 20:35:43 +00001756 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001757 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001758 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001759#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001760
Guido van Rossuma1065681999-01-25 23:20:23 +00001761 PyMem_DEL(argvlist);
1762
Fred Drake699f3522000-06-29 21:12:41 +00001763 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001764 return posix_error();
1765 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001766#if SIZEOF_LONG == SIZEOF_VOID_P
1767 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001768#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001769 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001770#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001771}
1772
1773
1774static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001775"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001776Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001777\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001778 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001779 path: path of executable file\n\
1780 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001781 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001782
1783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001784posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001785{
1786 char *path;
1787 PyObject *argv, *env;
1788 char **argvlist;
1789 char **envlist;
1790 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1791 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001792 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001793 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001794
1795 /* spawnve has four arguments: (mode, path, argv, env), where
1796 argv is a list or tuple of strings and env is a dictionary
1797 like posix.environ. */
1798
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001799 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001800 return NULL;
1801 if (PyList_Check(argv)) {
1802 argc = PyList_Size(argv);
1803 getitem = PyList_GetItem;
1804 }
1805 else if (PyTuple_Check(argv)) {
1806 argc = PyTuple_Size(argv);
1807 getitem = PyTuple_GetItem;
1808 }
1809 else {
Fred Drake661ea262000-10-24 19:57:45 +00001810 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001811 return NULL;
1812 }
1813 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001814 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001815 return NULL;
1816 }
1817
1818 argvlist = PyMem_NEW(char *, argc+1);
1819 if (argvlist == NULL) {
1820 PyErr_NoMemory();
1821 return NULL;
1822 }
1823 for (i = 0; i < argc; i++) {
1824 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001825 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001826 &argvlist[i]))
1827 {
1828 goto fail_1;
1829 }
1830 }
1831 argvlist[argc] = NULL;
1832
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001833 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001834 envlist = PyMem_NEW(char *, i + 1);
1835 if (envlist == NULL) {
1836 PyErr_NoMemory();
1837 goto fail_1;
1838 }
1839 envc = 0;
1840 keys = PyMapping_Keys(env);
1841 vals = PyMapping_Values(env);
1842 if (!keys || !vals)
1843 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001844
Guido van Rossuma1065681999-01-25 23:20:23 +00001845 for (pos = 0; pos < i; pos++) {
1846 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001847 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001848
1849 key = PyList_GetItem(keys, pos);
1850 val = PyList_GetItem(vals, pos);
1851 if (!key || !val)
1852 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001853
Fred Drake661ea262000-10-24 19:57:45 +00001854 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1855 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001856 {
1857 goto fail_2;
1858 }
Tim Petersc8996f52001-12-03 20:41:00 +00001859 len = PyString_Size(key) + PyString_Size(val) + 2;
1860 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001861 if (p == NULL) {
1862 PyErr_NoMemory();
1863 goto fail_2;
1864 }
Tim Petersc8996f52001-12-03 20:41:00 +00001865 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001866 envlist[envc++] = p;
1867 }
1868 envlist[envc] = 0;
1869
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001870#if defined(PYOS_OS2) && defined(PYCC_GCC)
1871 Py_BEGIN_ALLOW_THREADS
1872 spawnval = spawnve(mode, path, argvlist, envlist);
1873 Py_END_ALLOW_THREADS
1874#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001875 if (mode == _OLD_P_OVERLAY)
1876 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001877
1878 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001879 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001880 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001881#endif
Tim Peters25059d32001-12-07 20:35:43 +00001882
Fred Drake699f3522000-06-29 21:12:41 +00001883 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001884 (void) posix_error();
1885 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001886#if SIZEOF_LONG == SIZEOF_VOID_P
1887 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001888#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001889 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001890#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001891
1892 fail_2:
1893 while (--envc >= 0)
1894 PyMem_DEL(envlist[envc]);
1895 PyMem_DEL(envlist);
1896 fail_1:
1897 PyMem_DEL(argvlist);
1898 Py_XDECREF(vals);
1899 Py_XDECREF(keys);
1900 return res;
1901}
1902#endif /* HAVE_SPAWNV */
1903
1904
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001905#ifdef HAVE_FORK1
1906static char posix_fork1__doc__[] =
1907"fork1() -> pid\n\
1908Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1909\n\
1910Return 0 to child process and PID of child to parent process.";
1911
1912static PyObject *
1913posix_fork1(self, args)
1914 PyObject *self;
1915 PyObject *args;
1916{
1917 int pid;
1918 if (!PyArg_ParseTuple(args, ":fork1"))
1919 return NULL;
1920 pid = fork1();
1921 if (pid == -1)
1922 return posix_error();
1923 PyOS_AfterFork();
1924 return PyInt_FromLong((long)pid);
1925}
1926#endif
1927
1928
Guido van Rossumad0ee831995-03-01 10:34:45 +00001929#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001930static char posix_fork__doc__[] =
1931"fork() -> pid\n\
1932Fork a child process.\n\
1933\n\
1934Return 0 to child process and PID of child to parent process.";
1935
Barry Warsaw53699e91996-12-10 23:23:01 +00001936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001937posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001938{
1939 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001940 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001941 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001942 pid = fork();
1943 if (pid == -1)
1944 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001945 if (pid == 0)
1946 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001947 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001948}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001949#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001950
Fred Drake8cef4cf2000-06-28 16:40:38 +00001951#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1952#ifdef HAVE_PTY_H
1953#include <pty.h>
1954#else
1955#ifdef HAVE_LIBUTIL_H
1956#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001957#endif /* HAVE_LIBUTIL_H */
1958#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001959#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001960
Thomas Wouters70c21a12000-07-14 14:28:33 +00001961#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001962static char posix_openpty__doc__[] =
1963"openpty() -> (master_fd, slave_fd)\n\
1964Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1965
1966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001967posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001968{
1969 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001970#ifndef HAVE_OPENPTY
1971 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001972#endif
1973
Fred Drake8cef4cf2000-06-28 16:40:38 +00001974 if (!PyArg_ParseTuple(args, ":openpty"))
1975 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001976
1977#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001978 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1979 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001980#else
1981 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1982 if (slave_name == NULL)
1983 return posix_error();
1984
1985 slave_fd = open(slave_name, O_RDWR);
1986 if (slave_fd < 0)
1987 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001988#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001989
Fred Drake8cef4cf2000-06-28 16:40:38 +00001990 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001991
Fred Drake8cef4cf2000-06-28 16:40:38 +00001992}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001993#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001994
1995#ifdef HAVE_FORKPTY
1996static char posix_forkpty__doc__[] =
1997"forkpty() -> (pid, master_fd)\n\
1998Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1999Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
2000To both, return fd of newly opened pseudo-terminal.\n";
2001
2002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002003posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002004{
2005 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002006
Fred Drake8cef4cf2000-06-28 16:40:38 +00002007 if (!PyArg_ParseTuple(args, ":forkpty"))
2008 return NULL;
2009 pid = forkpty(&master_fd, NULL, NULL, NULL);
2010 if (pid == -1)
2011 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002012 if (pid == 0)
2013 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002014 return Py_BuildValue("(ii)", pid, master_fd);
2015}
2016#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002017
Guido van Rossumad0ee831995-03-01 10:34:45 +00002018#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002019static char posix_getegid__doc__[] =
2020"getegid() -> egid\n\
2021Return the current process's effective group id.";
2022
Barry Warsaw53699e91996-12-10 23:23:01 +00002023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002024posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002025{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002026 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002027 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002028 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002029}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002030#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002032
Guido van Rossumad0ee831995-03-01 10:34:45 +00002033#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002034static char posix_geteuid__doc__[] =
2035"geteuid() -> euid\n\
2036Return the current process's effective user id.";
2037
Barry Warsaw53699e91996-12-10 23:23:01 +00002038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002039posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002040{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002041 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002042 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002043 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002044}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002045#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002046
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002047
Guido van Rossumad0ee831995-03-01 10:34:45 +00002048#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002049static char posix_getgid__doc__[] =
2050"getgid() -> gid\n\
2051Return the current process's group id.";
2052
Barry Warsaw53699e91996-12-10 23:23:01 +00002053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002054posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002055{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002056 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002057 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002058 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002059}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002060#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002062
2063static char posix_getpid__doc__[] =
2064"getpid() -> pid\n\
2065Return the current process id";
2066
Barry Warsaw53699e91996-12-10 23:23:01 +00002067static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002068posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002069{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002070 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002071 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002072 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002073}
2074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
Fred Drakec9680921999-12-13 16:37:25 +00002076#ifdef HAVE_GETGROUPS
2077static char posix_getgroups__doc__[] = "\
2078getgroups() -> list of group IDs\n\
2079Return list of supplemental group IDs for the process.";
2080
2081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002082posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002083{
2084 PyObject *result = NULL;
2085
2086 if (PyArg_ParseTuple(args, ":getgroups")) {
2087#ifdef NGROUPS_MAX
2088#define MAX_GROUPS NGROUPS_MAX
2089#else
2090 /* defined to be 16 on Solaris7, so this should be a small number */
2091#define MAX_GROUPS 64
2092#endif
2093 gid_t grouplist[MAX_GROUPS];
2094 int n;
2095
2096 n = getgroups(MAX_GROUPS, grouplist);
2097 if (n < 0)
2098 posix_error();
2099 else {
2100 result = PyList_New(n);
2101 if (result != NULL) {
2102 PyObject *o;
2103 int i;
2104 for (i = 0; i < n; ++i) {
2105 o = PyInt_FromLong((long)grouplist[i]);
2106 if (o == NULL) {
2107 Py_DECREF(result);
2108 result = NULL;
2109 break;
2110 }
2111 PyList_SET_ITEM(result, i, o);
2112 }
2113 }
2114 }
2115 }
2116 return result;
2117}
2118#endif
2119
Guido van Rossumb6775db1994-08-01 11:34:53 +00002120#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002121static char posix_getpgrp__doc__[] =
2122"getpgrp() -> pgrp\n\
2123Return the current process group id.";
2124
Barry Warsaw53699e91996-12-10 23:23:01 +00002125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002126posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002127{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002128 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002129 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002130#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002131 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002132#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002133 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002134#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002135}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002136#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002137
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002138
Guido van Rossumb6775db1994-08-01 11:34:53 +00002139#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002140static char posix_setpgrp__doc__[] =
2141"setpgrp() -> None\n\
2142Make this process a session leader.";
2143
Barry Warsaw53699e91996-12-10 23:23:01 +00002144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002145posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002146{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002147 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002148 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002149#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002150 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002151#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002152 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002153#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002154 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002155 Py_INCREF(Py_None);
2156 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002157}
2158
Guido van Rossumb6775db1994-08-01 11:34:53 +00002159#endif /* HAVE_SETPGRP */
2160
Guido van Rossumad0ee831995-03-01 10:34:45 +00002161#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002162static char posix_getppid__doc__[] =
2163"getppid() -> ppid\n\
2164Return the parent's process id.";
2165
Barry Warsaw53699e91996-12-10 23:23:01 +00002166static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002167posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002168{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002169 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002170 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002171 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002172}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002173#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002175
Fred Drake12c6e2d1999-12-14 21:25:03 +00002176#ifdef HAVE_GETLOGIN
2177static char posix_getlogin__doc__[] = "\
2178getlogin() -> string\n\
2179Return the actual login name.";
2180
2181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002182posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002183{
2184 PyObject *result = NULL;
2185
2186 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002187 char *name;
2188 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002189
Fred Drakea30680b2000-12-06 21:24:28 +00002190 errno = 0;
2191 name = getlogin();
2192 if (name == NULL) {
2193 if (errno)
2194 posix_error();
2195 else
2196 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002197 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002198 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002199 else
2200 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002201 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002202 }
2203 return result;
2204}
2205#endif
2206
Guido van Rossumad0ee831995-03-01 10:34:45 +00002207#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002208static char posix_getuid__doc__[] =
2209"getuid() -> uid\n\
2210Return the current process's user id.";
2211
Barry Warsaw53699e91996-12-10 23:23:01 +00002212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002213posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002214{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002215 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002216 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002217 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002218}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002219#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002221
Guido van Rossumad0ee831995-03-01 10:34:45 +00002222#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002223static char posix_kill__doc__[] =
2224"kill(pid, sig) -> None\n\
2225Kill a process with a signal.";
2226
Barry Warsaw53699e91996-12-10 23:23:01 +00002227static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002228posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002229{
2230 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002231 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002232 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002233#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002234 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2235 APIRET rc;
2236 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002237 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002238
2239 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2240 APIRET rc;
2241 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002242 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002243
2244 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002245 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002246#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002247 if (kill(pid, sig) == -1)
2248 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002249#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002250 Py_INCREF(Py_None);
2251 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002252}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002253#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002254
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002255#ifdef HAVE_KILLPG
2256static char posix_killpg__doc__[] =
2257"killpg(pgid, sig) -> None\n\
2258Kill a process group with a signal.";
2259
2260static PyObject *
2261posix_killpg(PyObject *self, PyObject *args)
2262{
2263 int pgid, sig;
2264 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2265 return NULL;
2266 if (killpg(pgid, sig) == -1)
2267 return posix_error();
2268 Py_INCREF(Py_None);
2269 return Py_None;
2270}
2271#endif
2272
Guido van Rossumc0125471996-06-28 18:55:32 +00002273#ifdef HAVE_PLOCK
2274
2275#ifdef HAVE_SYS_LOCK_H
2276#include <sys/lock.h>
2277#endif
2278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279static char posix_plock__doc__[] =
2280"plock(op) -> None\n\
2281Lock program segments into memory.";
2282
Barry Warsaw53699e91996-12-10 23:23:01 +00002283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002284posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002285{
2286 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002287 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002288 return NULL;
2289 if (plock(op) == -1)
2290 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002291 Py_INCREF(Py_None);
2292 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002293}
2294#endif
2295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002296
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002297#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002298static char posix_popen__doc__[] =
2299"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2300Open a pipe to/from a command returning a file object.";
2301
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002302#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002303#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002304static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002305async_system(const char *command)
2306{
2307 char *p, errormsg[256], args[1024];
2308 RESULTCODES rcodes;
2309 APIRET rc;
2310 char *shell = getenv("COMSPEC");
2311 if (!shell)
2312 shell = "cmd";
2313
2314 strcpy(args, shell);
2315 p = &args[ strlen(args)+1 ];
2316 strcpy(p, "/c ");
2317 strcat(p, command);
2318 p += strlen(p) + 1;
2319 *p = '\0';
2320
2321 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002322 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002324 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002325 &rcodes, shell);
2326 return rc;
2327}
2328
Guido van Rossumd48f2521997-12-05 22:19:34 +00002329static FILE *
2330popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002331{
2332 HFILE rhan, whan;
2333 FILE *retfd = NULL;
2334 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2335
Guido van Rossumd48f2521997-12-05 22:19:34 +00002336 if (rc != NO_ERROR) {
2337 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002338 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002339 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002340
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002341 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2342 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002343
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002344 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2345 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002346
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002347 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2348 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002349
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002350 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002351 }
2352
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002353 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2354 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002355
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002356 if (rc == NO_ERROR)
2357 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2358
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002359 close(oldfd); /* And Close Saved STDOUT Handle */
2360 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002361
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002362 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2363 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002364
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002365 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2366 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002367
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002368 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2369 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002370
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002371 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002372 }
2373
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002374 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2375 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002376
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002377 if (rc == NO_ERROR)
2378 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2379
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002380 close(oldfd); /* And Close Saved STDIN Handle */
2381 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002382
Guido van Rossumd48f2521997-12-05 22:19:34 +00002383 } else {
2384 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002385 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002386 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002387}
2388
2389static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002390posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002391{
2392 char *name;
2393 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002394 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002395 FILE *fp;
2396 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002397 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002398 return NULL;
2399 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002400 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002401 Py_END_ALLOW_THREADS
2402 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002403 return os2_error(err);
2404
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002405 f = PyFile_FromFile(fp, name, mode, fclose);
2406 if (f != NULL)
2407 PyFile_SetBufSize(f, bufsize);
2408 return f;
2409}
2410
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002411#elif defined(PYCC_GCC)
2412
2413/* standard posix version of popen() support */
2414static PyObject *
2415posix_popen(PyObject *self, PyObject *args)
2416{
2417 char *name;
2418 char *mode = "r";
2419 int bufsize = -1;
2420 FILE *fp;
2421 PyObject *f;
2422 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2423 return NULL;
2424 Py_BEGIN_ALLOW_THREADS
2425 fp = popen(name, mode);
2426 Py_END_ALLOW_THREADS
2427 if (fp == NULL)
2428 return posix_error();
2429 f = PyFile_FromFile(fp, name, mode, pclose);
2430 if (f != NULL)
2431 PyFile_SetBufSize(f, bufsize);
2432 return f;
2433}
2434
2435/* fork() under OS/2 has lots'o'warts
2436 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2437 * most of this code is a ripoff of the win32 code, but using the
2438 * capabilities of EMX's C library routines
2439 */
2440
2441/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2442#define POPEN_1 1
2443#define POPEN_2 2
2444#define POPEN_3 3
2445#define POPEN_4 4
2446
2447static PyObject *_PyPopen(char *, int, int, int);
2448static int _PyPclose(FILE *file);
2449
2450/*
2451 * Internal dictionary mapping popen* file pointers to process handles,
2452 * for use when retrieving the process exit code. See _PyPclose() below
2453 * for more information on this dictionary's use.
2454 */
2455static PyObject *_PyPopenProcs = NULL;
2456
2457/* os2emx version of popen2()
2458 *
2459 * The result of this function is a pipe (file) connected to the
2460 * process's stdin, and a pipe connected to the process's stdout.
2461 */
2462
2463static PyObject *
2464os2emx_popen2(PyObject *self, PyObject *args)
2465{
2466 PyObject *f;
2467 int tm=0;
2468
2469 char *cmdstring;
2470 char *mode = "t";
2471 int bufsize = -1;
2472 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2473 return NULL;
2474
2475 if (*mode == 't')
2476 tm = O_TEXT;
2477 else if (*mode != 'b') {
2478 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2479 return NULL;
2480 } else
2481 tm = O_BINARY;
2482
2483 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2484
2485 return f;
2486}
2487
2488/*
2489 * Variation on os2emx.popen2
2490 *
2491 * The result of this function is 3 pipes - the process's stdin,
2492 * stdout and stderr
2493 */
2494
2495static PyObject *
2496os2emx_popen3(PyObject *self, PyObject *args)
2497{
2498 PyObject *f;
2499 int tm = 0;
2500
2501 char *cmdstring;
2502 char *mode = "t";
2503 int bufsize = -1;
2504 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2505 return NULL;
2506
2507 if (*mode == 't')
2508 tm = O_TEXT;
2509 else if (*mode != 'b') {
2510 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2511 return NULL;
2512 } else
2513 tm = O_BINARY;
2514
2515 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2516
2517 return f;
2518}
2519
2520/*
2521 * Variation on os2emx.popen2
2522 *
2523 * The result of this function is 2 pipes - the processes stdin,
2524 * and stdout+stderr combined as a single pipe.
2525 */
2526
2527static PyObject *
2528os2emx_popen4(PyObject *self, PyObject *args)
2529{
2530 PyObject *f;
2531 int tm = 0;
2532
2533 char *cmdstring;
2534 char *mode = "t";
2535 int bufsize = -1;
2536 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2537 return NULL;
2538
2539 if (*mode == 't')
2540 tm = O_TEXT;
2541 else if (*mode != 'b') {
2542 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2543 return NULL;
2544 } else
2545 tm = O_BINARY;
2546
2547 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2548
2549 return f;
2550}
2551
2552/* a couple of structures for convenient handling of multiple
2553 * file handles and pipes
2554 */
2555struct file_ref
2556{
2557 int handle;
2558 int flags;
2559};
2560
2561struct pipe_ref
2562{
2563 int rd;
2564 int wr;
2565};
2566
2567/* The following code is derived from the win32 code */
2568
2569static PyObject *
2570_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2571{
2572 struct file_ref stdio[3];
2573 struct pipe_ref p_fd[3];
2574 FILE *p_s[3];
2575 int file_count, i, pipe_err, pipe_pid;
2576 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2577 PyObject *f, *p_f[3];
2578
2579 /* file modes for subsequent fdopen's on pipe handles */
2580 if (mode == O_TEXT)
2581 {
2582 rd_mode = "rt";
2583 wr_mode = "wt";
2584 }
2585 else
2586 {
2587 rd_mode = "rb";
2588 wr_mode = "wb";
2589 }
2590
2591 /* prepare shell references */
2592 if ((shell = getenv("EMXSHELL")) == NULL)
2593 if ((shell = getenv("COMSPEC")) == NULL)
2594 {
2595 errno = ENOENT;
2596 return posix_error();
2597 }
2598
2599 sh_name = _getname(shell);
2600 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2601 opt = "/c";
2602 else
2603 opt = "-c";
2604
2605 /* save current stdio fds + their flags, and set not inheritable */
2606 i = pipe_err = 0;
2607 while (pipe_err >= 0 && i < 3)
2608 {
2609 pipe_err = stdio[i].handle = dup(i);
2610 stdio[i].flags = fcntl(i, F_GETFD, 0);
2611 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2612 i++;
2613 }
2614 if (pipe_err < 0)
2615 {
2616 /* didn't get them all saved - clean up and bail out */
2617 int saved_err = errno;
2618 while (i-- > 0)
2619 {
2620 close(stdio[i].handle);
2621 }
2622 errno = saved_err;
2623 return posix_error();
2624 }
2625
2626 /* create pipe ends */
2627 file_count = 2;
2628 if (n == POPEN_3)
2629 file_count = 3;
2630 i = pipe_err = 0;
2631 while ((pipe_err == 0) && (i < file_count))
2632 pipe_err = pipe((int *)&p_fd[i++]);
2633 if (pipe_err < 0)
2634 {
2635 /* didn't get them all made - clean up and bail out */
2636 while (i-- > 0)
2637 {
2638 close(p_fd[i].wr);
2639 close(p_fd[i].rd);
2640 }
2641 errno = EPIPE;
2642 return posix_error();
2643 }
2644
2645 /* change the actual standard IO streams over temporarily,
2646 * making the retained pipe ends non-inheritable
2647 */
2648 pipe_err = 0;
2649
2650 /* - stdin */
2651 if (dup2(p_fd[0].rd, 0) == 0)
2652 {
2653 close(p_fd[0].rd);
2654 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2655 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2656 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2657 {
2658 close(p_fd[0].wr);
2659 pipe_err = -1;
2660 }
2661 }
2662 else
2663 {
2664 pipe_err = -1;
2665 }
2666
2667 /* - stdout */
2668 if (pipe_err == 0)
2669 {
2670 if (dup2(p_fd[1].wr, 1) == 1)
2671 {
2672 close(p_fd[1].wr);
2673 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2674 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2675 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2676 {
2677 close(p_fd[1].rd);
2678 pipe_err = -1;
2679 }
2680 }
2681 else
2682 {
2683 pipe_err = -1;
2684 }
2685 }
2686
2687 /* - stderr, as required */
2688 if (pipe_err == 0)
2689 switch (n)
2690 {
2691 case POPEN_3:
2692 {
2693 if (dup2(p_fd[2].wr, 2) == 2)
2694 {
2695 close(p_fd[2].wr);
2696 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2697 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2698 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2699 {
2700 close(p_fd[2].rd);
2701 pipe_err = -1;
2702 }
2703 }
2704 else
2705 {
2706 pipe_err = -1;
2707 }
2708 break;
2709 }
2710
2711 case POPEN_4:
2712 {
2713 if (dup2(1, 2) != 2)
2714 {
2715 pipe_err = -1;
2716 }
2717 break;
2718 }
2719 }
2720
2721 /* spawn the child process */
2722 if (pipe_err == 0)
2723 {
2724 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2725 if (pipe_pid == -1)
2726 {
2727 pipe_err = -1;
2728 }
2729 else
2730 {
2731 /* save the PID into the FILE structure
2732 * NOTE: this implementation doesn't actually
2733 * take advantage of this, but do it for
2734 * completeness - AIM Apr01
2735 */
2736 for (i = 0; i < file_count; i++)
2737 p_s[i]->_pid = pipe_pid;
2738 }
2739 }
2740
2741 /* reset standard IO to normal */
2742 for (i = 0; i < 3; i++)
2743 {
2744 dup2(stdio[i].handle, i);
2745 fcntl(i, F_SETFD, stdio[i].flags);
2746 close(stdio[i].handle);
2747 }
2748
2749 /* if any remnant problems, clean up and bail out */
2750 if (pipe_err < 0)
2751 {
2752 for (i = 0; i < 3; i++)
2753 {
2754 close(p_fd[i].rd);
2755 close(p_fd[i].wr);
2756 }
2757 errno = EPIPE;
2758 return posix_error_with_filename(cmdstring);
2759 }
2760
2761 /* build tuple of file objects to return */
2762 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2763 PyFile_SetBufSize(p_f[0], bufsize);
2764 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2765 PyFile_SetBufSize(p_f[1], bufsize);
2766 if (n == POPEN_3)
2767 {
2768 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2769 PyFile_SetBufSize(p_f[0], bufsize);
2770 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2771 }
2772 else
2773 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2774
2775 /*
2776 * Insert the files we've created into the process dictionary
2777 * all referencing the list with the process handle and the
2778 * initial number of files (see description below in _PyPclose).
2779 * Since if _PyPclose later tried to wait on a process when all
2780 * handles weren't closed, it could create a deadlock with the
2781 * child, we spend some energy here to try to ensure that we
2782 * either insert all file handles into the dictionary or none
2783 * at all. It's a little clumsy with the various popen modes
2784 * and variable number of files involved.
2785 */
2786 if (!_PyPopenProcs)
2787 {
2788 _PyPopenProcs = PyDict_New();
2789 }
2790
2791 if (_PyPopenProcs)
2792 {
2793 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2794 int ins_rc[3];
2795
2796 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2797 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2798
2799 procObj = PyList_New(2);
2800 pidObj = PyInt_FromLong((long) pipe_pid);
2801 intObj = PyInt_FromLong((long) file_count);
2802
2803 if (procObj && pidObj && intObj)
2804 {
2805 PyList_SetItem(procObj, 0, pidObj);
2806 PyList_SetItem(procObj, 1, intObj);
2807
2808 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2809 if (fileObj[0])
2810 {
2811 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2812 fileObj[0],
2813 procObj);
2814 }
2815 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2816 if (fileObj[1])
2817 {
2818 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2819 fileObj[1],
2820 procObj);
2821 }
2822 if (file_count >= 3)
2823 {
2824 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2825 if (fileObj[2])
2826 {
2827 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2828 fileObj[2],
2829 procObj);
2830 }
2831 }
2832
2833 if (ins_rc[0] < 0 || !fileObj[0] ||
2834 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2835 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2836 {
2837 /* Something failed - remove any dictionary
2838 * entries that did make it.
2839 */
2840 if (!ins_rc[0] && fileObj[0])
2841 {
2842 PyDict_DelItem(_PyPopenProcs,
2843 fileObj[0]);
2844 }
2845 if (!ins_rc[1] && fileObj[1])
2846 {
2847 PyDict_DelItem(_PyPopenProcs,
2848 fileObj[1]);
2849 }
2850 if (!ins_rc[2] && fileObj[2])
2851 {
2852 PyDict_DelItem(_PyPopenProcs,
2853 fileObj[2]);
2854 }
2855 }
2856 }
2857
2858 /*
2859 * Clean up our localized references for the dictionary keys
2860 * and value since PyDict_SetItem will Py_INCREF any copies
2861 * that got placed in the dictionary.
2862 */
2863 Py_XDECREF(procObj);
2864 Py_XDECREF(fileObj[0]);
2865 Py_XDECREF(fileObj[1]);
2866 Py_XDECREF(fileObj[2]);
2867 }
2868
2869 /* Child is launched. */
2870 return f;
2871}
2872
2873/*
2874 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2875 * exit code for the child process and return as a result of the close.
2876 *
2877 * This function uses the _PyPopenProcs dictionary in order to map the
2878 * input file pointer to information about the process that was
2879 * originally created by the popen* call that created the file pointer.
2880 * The dictionary uses the file pointer as a key (with one entry
2881 * inserted for each file returned by the original popen* call) and a
2882 * single list object as the value for all files from a single call.
2883 * The list object contains the Win32 process handle at [0], and a file
2884 * count at [1], which is initialized to the total number of file
2885 * handles using that list.
2886 *
2887 * This function closes whichever handle it is passed, and decrements
2888 * the file count in the dictionary for the process handle pointed to
2889 * by this file. On the last close (when the file count reaches zero),
2890 * this function will wait for the child process and then return its
2891 * exit code as the result of the close() operation. This permits the
2892 * files to be closed in any order - it is always the close() of the
2893 * final handle that will return the exit code.
2894 */
2895
2896 /* RED_FLAG 31-Aug-2000 Tim
2897 * This is always called (today!) between a pair of
2898 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2899 * macros. So the thread running this has no valid thread state, as
2900 * far as Python is concerned. However, this calls some Python API
2901 * functions that cannot be called safely without a valid thread
2902 * state, in particular PyDict_GetItem.
2903 * As a temporary hack (although it may last for years ...), we
2904 * *rely* on not having a valid thread state in this function, in
2905 * order to create our own "from scratch".
2906 * This will deadlock if _PyPclose is ever called by a thread
2907 * holding the global lock.
2908 * (The OS/2 EMX thread support appears to cover the case where the
2909 * lock is already held - AIM Apr01)
2910 */
2911
2912static int _PyPclose(FILE *file)
2913{
2914 int result;
2915 int exit_code;
2916 int pipe_pid;
2917 PyObject *procObj, *pidObj, *intObj, *fileObj;
2918 int file_count;
2919#ifdef WITH_THREAD
2920 PyInterpreterState* pInterpreterState;
2921 PyThreadState* pThreadState;
2922#endif
2923
2924 /* Close the file handle first, to ensure it can't block the
2925 * child from exiting if it's the last handle.
2926 */
2927 result = fclose(file);
2928
2929#ifdef WITH_THREAD
2930 /* Bootstrap a valid thread state into existence. */
2931 pInterpreterState = PyInterpreterState_New();
2932 if (!pInterpreterState) {
2933 /* Well, we're hosed now! We don't have a thread
2934 * state, so can't call a nice error routine, or raise
2935 * an exception. Just die.
2936 */
2937 Py_FatalError("unable to allocate interpreter state "
2938 "when closing popen object.");
2939 return -1; /* unreachable */
2940 }
2941 pThreadState = PyThreadState_New(pInterpreterState);
2942 if (!pThreadState) {
2943 Py_FatalError("unable to allocate thread state "
2944 "when closing popen object.");
2945 return -1; /* unreachable */
2946 }
2947 /* Grab the global lock. Note that this will deadlock if the
2948 * current thread already has the lock! (see RED_FLAG comments
2949 * before this function)
2950 */
2951 PyEval_RestoreThread(pThreadState);
2952#endif
2953
2954 if (_PyPopenProcs)
2955 {
2956 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2957 (procObj = PyDict_GetItem(_PyPopenProcs,
2958 fileObj)) != NULL &&
2959 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2960 (intObj = PyList_GetItem(procObj,1)) != NULL)
2961 {
2962 pipe_pid = (int) PyInt_AsLong(pidObj);
2963 file_count = (int) PyInt_AsLong(intObj);
2964
2965 if (file_count > 1)
2966 {
2967 /* Still other files referencing process */
2968 file_count--;
2969 PyList_SetItem(procObj,1,
2970 PyInt_FromLong((long) file_count));
2971 }
2972 else
2973 {
2974 /* Last file for this process */
2975 if (result != EOF &&
2976 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2977 {
2978 /* extract exit status */
2979 if (WIFEXITED(exit_code))
2980 {
2981 result = WEXITSTATUS(exit_code);
2982 }
2983 else
2984 {
2985 errno = EPIPE;
2986 result = -1;
2987 }
2988 }
2989 else
2990 {
2991 /* Indicate failure - this will cause the file object
2992 * to raise an I/O error and translate the last
2993 * error code from errno. We do have a problem with
2994 * last errors that overlap the normal errno table,
2995 * but that's a consistent problem with the file object.
2996 */
2997 result = -1;
2998 }
2999 }
3000
3001 /* Remove this file pointer from dictionary */
3002 PyDict_DelItem(_PyPopenProcs, fileObj);
3003
3004 if (PyDict_Size(_PyPopenProcs) == 0)
3005 {
3006 Py_DECREF(_PyPopenProcs);
3007 _PyPopenProcs = NULL;
3008 }
3009
3010 } /* if object retrieval ok */
3011
3012 Py_XDECREF(fileObj);
3013 } /* if _PyPopenProcs */
3014
3015#ifdef WITH_THREAD
3016 /* Tear down the thread & interpreter states.
3017 * Note that interpreter state clear & delete functions automatically
3018 * call the thread clear & delete functions, and indeed insist on
3019 * doing that themselves. The lock must be held during the clear, but
3020 * need not be held during the delete.
3021 */
3022 PyInterpreterState_Clear(pInterpreterState);
3023 PyEval_ReleaseThread(pThreadState);
3024 PyInterpreterState_Delete(pInterpreterState);
3025#endif
3026
3027 return result;
3028}
3029
3030#endif /* PYCC_??? */
3031
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003032#elif defined(MS_WIN32)
3033
3034/*
3035 * Portable 'popen' replacement for Win32.
3036 *
3037 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3038 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003039 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003040 */
3041
3042#include <malloc.h>
3043#include <io.h>
3044#include <fcntl.h>
3045
3046/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3047#define POPEN_1 1
3048#define POPEN_2 2
3049#define POPEN_3 3
3050#define POPEN_4 4
3051
3052static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003053static int _PyPclose(FILE *file);
3054
3055/*
3056 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003057 * for use when retrieving the process exit code. See _PyPclose() below
3058 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003059 */
3060static PyObject *_PyPopenProcs = NULL;
3061
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003062
3063/* popen that works from a GUI.
3064 *
3065 * The result of this function is a pipe (file) connected to the
3066 * processes stdin or stdout, depending on the requested mode.
3067 */
3068
3069static PyObject *
3070posix_popen(PyObject *self, PyObject *args)
3071{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003072 PyObject *f, *s;
3073 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003074
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003075 char *cmdstring;
3076 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003077 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003078 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003079 return NULL;
3080
3081 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003082
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003083 if (*mode == 'r')
3084 tm = _O_RDONLY;
3085 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003086 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003087 return NULL;
3088 } else
3089 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003090
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003091 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003092 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003093 return NULL;
3094 }
3095
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003096 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003097 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003098 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003099 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003100 else
3101 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3102
3103 return f;
3104}
3105
3106/* Variation on win32pipe.popen
3107 *
3108 * The result of this function is a pipe (file) connected to the
3109 * process's stdin, and a pipe connected to the process's stdout.
3110 */
3111
3112static PyObject *
3113win32_popen2(PyObject *self, PyObject *args)
3114{
3115 PyObject *f;
3116 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003117
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003118 char *cmdstring;
3119 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003120 int bufsize = -1;
3121 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003122 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003123
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003124 if (*mode == 't')
3125 tm = _O_TEXT;
3126 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003127 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003128 return NULL;
3129 } else
3130 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003131
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003132 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003133 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003134 return NULL;
3135 }
3136
3137 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003138
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003139 return f;
3140}
3141
3142/*
3143 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003144 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003145 * The result of this function is 3 pipes - the process's stdin,
3146 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003147 */
3148
3149static PyObject *
3150win32_popen3(PyObject *self, PyObject *args)
3151{
3152 PyObject *f;
3153 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003154
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003155 char *cmdstring;
3156 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003157 int bufsize = -1;
3158 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003159 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003160
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003161 if (*mode == 't')
3162 tm = _O_TEXT;
3163 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003164 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003165 return NULL;
3166 } else
3167 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003168
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003169 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003170 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003171 return NULL;
3172 }
3173
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003174 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003175
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003176 return f;
3177}
3178
3179/*
3180 * Variation on win32pipe.popen
3181 *
Tim Peters5aa91602002-01-30 05:46:57 +00003182 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003183 * and stdout+stderr combined as a single pipe.
3184 */
3185
3186static PyObject *
3187win32_popen4(PyObject *self, PyObject *args)
3188{
3189 PyObject *f;
3190 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003191
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003192 char *cmdstring;
3193 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003194 int bufsize = -1;
3195 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003196 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003197
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003198 if (*mode == 't')
3199 tm = _O_TEXT;
3200 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003201 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003202 return NULL;
3203 } else
3204 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003205
3206 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003207 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003208 return NULL;
3209 }
3210
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003211 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003212
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003213 return f;
3214}
3215
Mark Hammond08501372001-01-31 07:30:29 +00003216static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003217_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003218 HANDLE hStdin,
3219 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003220 HANDLE hStderr,
3221 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003222{
3223 PROCESS_INFORMATION piProcInfo;
3224 STARTUPINFO siStartInfo;
3225 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003226 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003227 int i;
3228 int x;
3229
3230 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003231 char *comshell;
3232
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003233 s1 = (char *)_alloca(i);
3234 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3235 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003236
3237 /* Explicitly check if we are using COMMAND.COM. If we are
3238 * then use the w9xpopen hack.
3239 */
3240 comshell = s1 + x;
3241 while (comshell >= s1 && *comshell != '\\')
3242 --comshell;
3243 ++comshell;
3244
3245 if (GetVersion() < 0x80000000 &&
3246 _stricmp(comshell, "command.com") != 0) {
3247 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003248 x = i + strlen(s3) + strlen(cmdstring) + 1;
3249 s2 = (char *)_alloca(x);
3250 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003251 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003252 }
3253 else {
3254 /*
Tim Peters402d5982001-08-27 06:37:48 +00003255 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3256 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003257 */
Mark Hammond08501372001-01-31 07:30:29 +00003258 char modulepath[_MAX_PATH];
3259 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003260 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3261 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003262 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003263 x = i+1;
3264 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003265 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003266 strncat(modulepath,
3267 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003268 (sizeof(modulepath)/sizeof(modulepath[0]))
3269 -strlen(modulepath));
3270 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003271 /* Eeek - file-not-found - possibly an embedding
3272 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003273 */
Tim Peters5aa91602002-01-30 05:46:57 +00003274 strncpy(modulepath,
3275 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003276 sizeof(modulepath)/sizeof(modulepath[0]));
3277 if (modulepath[strlen(modulepath)-1] != '\\')
3278 strcat(modulepath, "\\");
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 /* No where else to look - raise an easily identifiable
3284 error, rather than leaving Windows to report
3285 "file not found" - as the user is probably blissfully
3286 unaware this shim EXE is used, and it will confuse them.
3287 (well, it confused me for a while ;-)
3288 */
3289 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003290 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003291 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003292 "for popen to work with your shell "
3293 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003294 szConsoleSpawn);
3295 return FALSE;
3296 }
3297 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003298 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003299 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003300 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003301
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003302 s2 = (char *)_alloca(x);
3303 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003304 /* To maintain correct argument passing semantics,
3305 we pass the command-line as it stands, and allow
3306 quoting to be applied. w9xpopen.exe will then
3307 use its argv vector, and re-quote the necessary
3308 args for the ultimate child process.
3309 */
Tim Peters75cdad52001-11-28 22:07:30 +00003310 PyOS_snprintf(
3311 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003312 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003313 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003314 s1,
3315 s3,
3316 cmdstring);
3317 }
3318 }
3319
3320 /* Could be an else here to try cmd.exe / command.com in the path
3321 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003322 else {
Tim Peters402d5982001-08-27 06:37:48 +00003323 PyErr_SetString(PyExc_RuntimeError,
3324 "Cannot locate a COMSPEC environment variable to "
3325 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003326 return FALSE;
3327 }
Tim Peters5aa91602002-01-30 05:46:57 +00003328
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003329 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3330 siStartInfo.cb = sizeof(STARTUPINFO);
3331 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3332 siStartInfo.hStdInput = hStdin;
3333 siStartInfo.hStdOutput = hStdout;
3334 siStartInfo.hStdError = hStderr;
3335 siStartInfo.wShowWindow = SW_HIDE;
3336
3337 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003338 s2,
3339 NULL,
3340 NULL,
3341 TRUE,
3342 CREATE_NEW_CONSOLE,
3343 NULL,
3344 NULL,
3345 &siStartInfo,
3346 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003347 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003348 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003349
Mark Hammondb37a3732000-08-14 04:47:33 +00003350 /* Return process handle */
3351 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003352 return TRUE;
3353 }
Tim Peters402d5982001-08-27 06:37:48 +00003354 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003355 return FALSE;
3356}
3357
3358/* The following code is based off of KB: Q190351 */
3359
3360static PyObject *
3361_PyPopen(char *cmdstring, int mode, int n)
3362{
3363 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3364 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003365 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003366
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003367 SECURITY_ATTRIBUTES saAttr;
3368 BOOL fSuccess;
3369 int fd1, fd2, fd3;
3370 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003371 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003372 PyObject *f;
3373
3374 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3375 saAttr.bInheritHandle = TRUE;
3376 saAttr.lpSecurityDescriptor = NULL;
3377
3378 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3379 return win32_error("CreatePipe", NULL);
3380
3381 /* Create new output read handle and the input write handle. Set
3382 * the inheritance properties to FALSE. Otherwise, the child inherits
3383 * the these handles; resulting in non-closeable handles to the pipes
3384 * being created. */
3385 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003386 GetCurrentProcess(), &hChildStdinWrDup, 0,
3387 FALSE,
3388 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003389 if (!fSuccess)
3390 return win32_error("DuplicateHandle", NULL);
3391
3392 /* Close the inheritable version of ChildStdin
3393 that we're using. */
3394 CloseHandle(hChildStdinWr);
3395
3396 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3397 return win32_error("CreatePipe", NULL);
3398
3399 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003400 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3401 FALSE, 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 ChildStdout
3406 that we're using. */
3407 CloseHandle(hChildStdoutRd);
3408
3409 if (n != POPEN_4) {
3410 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3411 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003412 fSuccess = DuplicateHandle(GetCurrentProcess(),
3413 hChildStderrRd,
3414 GetCurrentProcess(),
3415 &hChildStderrRdDup, 0,
3416 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003417 if (!fSuccess)
3418 return win32_error("DuplicateHandle", NULL);
3419 /* Close the inheritable version of ChildStdErr that we're using. */
3420 CloseHandle(hChildStderrRd);
3421 }
Tim Peters5aa91602002-01-30 05:46:57 +00003422
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003423 switch (n) {
3424 case POPEN_1:
3425 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3426 case _O_WRONLY | _O_TEXT:
3427 /* Case for writing to child Stdin in text mode. */
3428 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3429 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003430 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003431 PyFile_SetBufSize(f, 0);
3432 /* We don't care about these pipes anymore, so close them. */
3433 CloseHandle(hChildStdoutRdDup);
3434 CloseHandle(hChildStderrRdDup);
3435 break;
3436
3437 case _O_RDONLY | _O_TEXT:
3438 /* Case for reading from child Stdout in text mode. */
3439 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3440 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003441 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003442 PyFile_SetBufSize(f, 0);
3443 /* We don't care about these pipes anymore, so close them. */
3444 CloseHandle(hChildStdinWrDup);
3445 CloseHandle(hChildStderrRdDup);
3446 break;
3447
3448 case _O_RDONLY | _O_BINARY:
3449 /* Case for readinig from child Stdout in binary mode. */
3450 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3451 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003452 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003453 PyFile_SetBufSize(f, 0);
3454 /* We don't care about these pipes anymore, so close them. */
3455 CloseHandle(hChildStdinWrDup);
3456 CloseHandle(hChildStderrRdDup);
3457 break;
3458
3459 case _O_WRONLY | _O_BINARY:
3460 /* Case for writing to child Stdin in binary mode. */
3461 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3462 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003463 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003464 PyFile_SetBufSize(f, 0);
3465 /* We don't care about these pipes anymore, so close them. */
3466 CloseHandle(hChildStdoutRdDup);
3467 CloseHandle(hChildStderrRdDup);
3468 break;
3469 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003470 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003471 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003472
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003473 case POPEN_2:
3474 case POPEN_4:
3475 {
3476 char *m1, *m2;
3477 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003478
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003479 if (mode && _O_TEXT) {
3480 m1 = "r";
3481 m2 = "w";
3482 } else {
3483 m1 = "rb";
3484 m2 = "wb";
3485 }
3486
3487 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3488 f1 = _fdopen(fd1, m2);
3489 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3490 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003491 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003492 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003493 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003494 PyFile_SetBufSize(p2, 0);
3495
3496 if (n != 4)
3497 CloseHandle(hChildStderrRdDup);
3498
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003499 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003500 Py_XDECREF(p1);
3501 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003502 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003503 break;
3504 }
Tim Peters5aa91602002-01-30 05:46:57 +00003505
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003506 case POPEN_3:
3507 {
3508 char *m1, *m2;
3509 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003510
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003511 if (mode && _O_TEXT) {
3512 m1 = "r";
3513 m2 = "w";
3514 } else {
3515 m1 = "rb";
3516 m2 = "wb";
3517 }
3518
3519 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3520 f1 = _fdopen(fd1, m2);
3521 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3522 f2 = _fdopen(fd2, m1);
3523 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3524 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003525 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003526 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3527 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003528 PyFile_SetBufSize(p1, 0);
3529 PyFile_SetBufSize(p2, 0);
3530 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003531 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003532 Py_XDECREF(p1);
3533 Py_XDECREF(p2);
3534 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003535 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003536 break;
3537 }
3538 }
3539
3540 if (n == POPEN_4) {
3541 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003542 hChildStdinRd,
3543 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003544 hChildStdoutWr,
3545 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003546 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003547 }
3548 else {
3549 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003550 hChildStdinRd,
3551 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003552 hChildStderrWr,
3553 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003554 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003555 }
3556
Mark Hammondb37a3732000-08-14 04:47:33 +00003557 /*
3558 * Insert the files we've created into the process dictionary
3559 * all referencing the list with the process handle and the
3560 * initial number of files (see description below in _PyPclose).
3561 * Since if _PyPclose later tried to wait on a process when all
3562 * handles weren't closed, it could create a deadlock with the
3563 * child, we spend some energy here to try to ensure that we
3564 * either insert all file handles into the dictionary or none
3565 * at all. It's a little clumsy with the various popen modes
3566 * and variable number of files involved.
3567 */
3568 if (!_PyPopenProcs) {
3569 _PyPopenProcs = PyDict_New();
3570 }
3571
3572 if (_PyPopenProcs) {
3573 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3574 int ins_rc[3];
3575
3576 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3577 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3578
3579 procObj = PyList_New(2);
3580 hProcessObj = PyLong_FromVoidPtr(hProcess);
3581 intObj = PyInt_FromLong(file_count);
3582
3583 if (procObj && hProcessObj && intObj) {
3584 PyList_SetItem(procObj,0,hProcessObj);
3585 PyList_SetItem(procObj,1,intObj);
3586
3587 fileObj[0] = PyLong_FromVoidPtr(f1);
3588 if (fileObj[0]) {
3589 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3590 fileObj[0],
3591 procObj);
3592 }
3593 if (file_count >= 2) {
3594 fileObj[1] = PyLong_FromVoidPtr(f2);
3595 if (fileObj[1]) {
3596 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3597 fileObj[1],
3598 procObj);
3599 }
3600 }
3601 if (file_count >= 3) {
3602 fileObj[2] = PyLong_FromVoidPtr(f3);
3603 if (fileObj[2]) {
3604 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3605 fileObj[2],
3606 procObj);
3607 }
3608 }
3609
3610 if (ins_rc[0] < 0 || !fileObj[0] ||
3611 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3612 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3613 /* Something failed - remove any dictionary
3614 * entries that did make it.
3615 */
3616 if (!ins_rc[0] && fileObj[0]) {
3617 PyDict_DelItem(_PyPopenProcs,
3618 fileObj[0]);
3619 }
3620 if (!ins_rc[1] && fileObj[1]) {
3621 PyDict_DelItem(_PyPopenProcs,
3622 fileObj[1]);
3623 }
3624 if (!ins_rc[2] && fileObj[2]) {
3625 PyDict_DelItem(_PyPopenProcs,
3626 fileObj[2]);
3627 }
3628 }
3629 }
Tim Peters5aa91602002-01-30 05:46:57 +00003630
Mark Hammondb37a3732000-08-14 04:47:33 +00003631 /*
3632 * Clean up our localized references for the dictionary keys
3633 * and value since PyDict_SetItem will Py_INCREF any copies
3634 * that got placed in the dictionary.
3635 */
3636 Py_XDECREF(procObj);
3637 Py_XDECREF(fileObj[0]);
3638 Py_XDECREF(fileObj[1]);
3639 Py_XDECREF(fileObj[2]);
3640 }
3641
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003642 /* Child is launched. Close the parents copy of those pipe
3643 * handles that only the child should have open. You need to
3644 * make sure that no handles to the write end of the output pipe
3645 * are maintained in this process or else the pipe will not close
3646 * when the child process exits and the ReadFile will hang. */
3647
3648 if (!CloseHandle(hChildStdinRd))
3649 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003650
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003651 if (!CloseHandle(hChildStdoutWr))
3652 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003653
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003654 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3655 return win32_error("CloseHandle", NULL);
3656
3657 return f;
3658}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003659
3660/*
3661 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3662 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003663 *
3664 * This function uses the _PyPopenProcs dictionary in order to map the
3665 * input file pointer to information about the process that was
3666 * originally created by the popen* call that created the file pointer.
3667 * The dictionary uses the file pointer as a key (with one entry
3668 * inserted for each file returned by the original popen* call) and a
3669 * single list object as the value for all files from a single call.
3670 * The list object contains the Win32 process handle at [0], and a file
3671 * count at [1], which is initialized to the total number of file
3672 * handles using that list.
3673 *
3674 * This function closes whichever handle it is passed, and decrements
3675 * the file count in the dictionary for the process handle pointed to
3676 * by this file. On the last close (when the file count reaches zero),
3677 * this function will wait for the child process and then return its
3678 * exit code as the result of the close() operation. This permits the
3679 * files to be closed in any order - it is always the close() of the
3680 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003681 */
Tim Peters736aa322000-09-01 06:51:24 +00003682
3683 /* RED_FLAG 31-Aug-2000 Tim
3684 * This is always called (today!) between a pair of
3685 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3686 * macros. So the thread running this has no valid thread state, as
3687 * far as Python is concerned. However, this calls some Python API
3688 * functions that cannot be called safely without a valid thread
3689 * state, in particular PyDict_GetItem.
3690 * As a temporary hack (although it may last for years ...), we
3691 * *rely* on not having a valid thread state in this function, in
3692 * order to create our own "from scratch".
3693 * This will deadlock if _PyPclose is ever called by a thread
3694 * holding the global lock.
3695 */
3696
Fredrik Lundh56055a42000-07-23 19:47:12 +00003697static int _PyPclose(FILE *file)
3698{
Fredrik Lundh20318932000-07-26 17:29:12 +00003699 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003700 DWORD exit_code;
3701 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003702 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3703 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003704#ifdef WITH_THREAD
3705 PyInterpreterState* pInterpreterState;
3706 PyThreadState* pThreadState;
3707#endif
3708
Fredrik Lundh20318932000-07-26 17:29:12 +00003709 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003710 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003711 */
3712 result = fclose(file);
3713
Tim Peters736aa322000-09-01 06:51:24 +00003714#ifdef WITH_THREAD
3715 /* Bootstrap a valid thread state into existence. */
3716 pInterpreterState = PyInterpreterState_New();
3717 if (!pInterpreterState) {
3718 /* Well, we're hosed now! We don't have a thread
3719 * state, so can't call a nice error routine, or raise
3720 * an exception. Just die.
3721 */
3722 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003723 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003724 return -1; /* unreachable */
3725 }
3726 pThreadState = PyThreadState_New(pInterpreterState);
3727 if (!pThreadState) {
3728 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003729 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003730 return -1; /* unreachable */
3731 }
3732 /* Grab the global lock. Note that this will deadlock if the
3733 * current thread already has the lock! (see RED_FLAG comments
3734 * before this function)
3735 */
3736 PyEval_RestoreThread(pThreadState);
3737#endif
3738
Fredrik Lundh56055a42000-07-23 19:47:12 +00003739 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003740 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3741 (procObj = PyDict_GetItem(_PyPopenProcs,
3742 fileObj)) != NULL &&
3743 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3744 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3745
3746 hProcess = PyLong_AsVoidPtr(hProcessObj);
3747 file_count = PyInt_AsLong(intObj);
3748
3749 if (file_count > 1) {
3750 /* Still other files referencing process */
3751 file_count--;
3752 PyList_SetItem(procObj,1,
3753 PyInt_FromLong(file_count));
3754 } else {
3755 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003756 if (result != EOF &&
3757 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3758 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003759 /* Possible truncation here in 16-bit environments, but
3760 * real exit codes are just the lower byte in any event.
3761 */
3762 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003763 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003764 /* Indicate failure - this will cause the file object
3765 * to raise an I/O error and translate the last Win32
3766 * error code from errno. We do have a problem with
3767 * last errors that overlap the normal errno table,
3768 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003769 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003770 if (result != EOF) {
3771 /* If the error wasn't from the fclose(), then
3772 * set errno for the file object error handling.
3773 */
3774 errno = GetLastError();
3775 }
3776 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003777 }
3778
3779 /* Free up the native handle at this point */
3780 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003781 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003782
Mark Hammondb37a3732000-08-14 04:47:33 +00003783 /* Remove this file pointer from dictionary */
3784 PyDict_DelItem(_PyPopenProcs, fileObj);
3785
3786 if (PyDict_Size(_PyPopenProcs) == 0) {
3787 Py_DECREF(_PyPopenProcs);
3788 _PyPopenProcs = NULL;
3789 }
3790
3791 } /* if object retrieval ok */
3792
3793 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003794 } /* if _PyPopenProcs */
3795
Tim Peters736aa322000-09-01 06:51:24 +00003796#ifdef WITH_THREAD
3797 /* Tear down the thread & interpreter states.
3798 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003799 * call the thread clear & delete functions, and indeed insist on
3800 * doing that themselves. The lock must be held during the clear, but
3801 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003802 */
3803 PyInterpreterState_Clear(pInterpreterState);
3804 PyEval_ReleaseThread(pThreadState);
3805 PyInterpreterState_Delete(pInterpreterState);
3806#endif
3807
Fredrik Lundh56055a42000-07-23 19:47:12 +00003808 return result;
3809}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003810
3811#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003813posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003814{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003815 char *name;
3816 char *mode = "r";
3817 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003818 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003819 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003820 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003821 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003822 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003823 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003824 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003825 if (fp == NULL)
3826 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003827 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003828 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003829 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003830 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003831}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003832
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003833#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003834#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003836
Guido van Rossumb6775db1994-08-01 11:34:53 +00003837#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003838static char posix_setuid__doc__[] =
3839"setuid(uid) -> None\n\
3840Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003842posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003843{
3844 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003845 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003846 return NULL;
3847 if (setuid(uid) < 0)
3848 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003849 Py_INCREF(Py_None);
3850 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003851}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003852#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003853
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003854
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003855#ifdef HAVE_SETEUID
3856static char posix_seteuid__doc__[] =
3857"seteuid(uid) -> None\n\
3858Set the current process's effective user id.";
3859static PyObject *
3860posix_seteuid (PyObject *self, PyObject *args)
3861{
3862 int euid;
3863 if (!PyArg_ParseTuple(args, "i", &euid)) {
3864 return NULL;
3865 } else if (seteuid(euid) < 0) {
3866 return posix_error();
3867 } else {
3868 Py_INCREF(Py_None);
3869 return Py_None;
3870 }
3871}
3872#endif /* HAVE_SETEUID */
3873
3874#ifdef HAVE_SETEGID
3875static char posix_setegid__doc__[] =
3876"setegid(gid) -> None\n\
3877Set the current process's effective group id.";
3878static PyObject *
3879posix_setegid (PyObject *self, PyObject *args)
3880{
3881 int egid;
3882 if (!PyArg_ParseTuple(args, "i", &egid)) {
3883 return NULL;
3884 } else if (setegid(egid) < 0) {
3885 return posix_error();
3886 } else {
3887 Py_INCREF(Py_None);
3888 return Py_None;
3889 }
3890}
3891#endif /* HAVE_SETEGID */
3892
3893#ifdef HAVE_SETREUID
3894static char posix_setreuid__doc__[] =
3895"seteuid(ruid, euid) -> None\n\
3896Set the current process's real and effective user ids.";
3897static PyObject *
3898posix_setreuid (PyObject *self, PyObject *args)
3899{
3900 int ruid, euid;
3901 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3902 return NULL;
3903 } else if (setreuid(ruid, euid) < 0) {
3904 return posix_error();
3905 } else {
3906 Py_INCREF(Py_None);
3907 return Py_None;
3908 }
3909}
3910#endif /* HAVE_SETREUID */
3911
3912#ifdef HAVE_SETREGID
3913static char posix_setregid__doc__[] =
3914"setegid(rgid, egid) -> None\n\
3915Set the current process's real and effective group ids.";
3916static PyObject *
3917posix_setregid (PyObject *self, PyObject *args)
3918{
3919 int rgid, egid;
3920 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3921 return NULL;
3922 } else if (setregid(rgid, egid) < 0) {
3923 return posix_error();
3924 } else {
3925 Py_INCREF(Py_None);
3926 return Py_None;
3927 }
3928}
3929#endif /* HAVE_SETREGID */
3930
Guido van Rossumb6775db1994-08-01 11:34:53 +00003931#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003932static char posix_setgid__doc__[] =
3933"setgid(gid) -> None\n\
3934Set the current process's group id.";
3935
Barry Warsaw53699e91996-12-10 23:23:01 +00003936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003937posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003938{
3939 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003940 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003941 return NULL;
3942 if (setgid(gid) < 0)
3943 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003944 Py_INCREF(Py_None);
3945 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003946}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003947#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003948
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003949#ifdef HAVE_SETGROUPS
3950static char posix_setgroups__doc__[] =
3951"setgroups(list) -> None\n\
3952Set the groups of the current process to list.";
3953
3954static PyObject *
3955posix_setgroups(PyObject *self, PyObject *args)
3956{
3957 PyObject *groups;
3958 int i, len;
3959 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003960
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003961 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3962 return NULL;
3963 if (!PySequence_Check(groups)) {
3964 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3965 return NULL;
3966 }
3967 len = PySequence_Size(groups);
3968 if (len > MAX_GROUPS) {
3969 PyErr_SetString(PyExc_ValueError, "too many groups");
3970 return NULL;
3971 }
3972 for(i = 0; i < len; i++) {
3973 PyObject *elem;
3974 elem = PySequence_GetItem(groups, i);
3975 if (!elem)
3976 return NULL;
3977 if (!PyInt_Check(elem)) {
3978 PyErr_SetString(PyExc_TypeError,
3979 "groups must be integers");
3980 Py_DECREF(elem);
3981 return NULL;
3982 }
3983 /* XXX: check that value fits into gid_t. */
3984 grouplist[i] = PyInt_AsLong(elem);
3985 Py_DECREF(elem);
3986 }
3987
3988 if (setgroups(len, grouplist) < 0)
3989 return posix_error();
3990 Py_INCREF(Py_None);
3991 return Py_None;
3992}
3993#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003994
Guido van Rossumb6775db1994-08-01 11:34:53 +00003995#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003996static char posix_waitpid__doc__[] =
3997"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003998Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003999
Barry Warsaw53699e91996-12-10 23:23:01 +00004000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004001posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004002{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004003 int pid, options;
4004#ifdef UNION_WAIT
4005 union wait status;
4006#define status_i (status.w_status)
4007#else
4008 int status;
4009#define status_i status
4010#endif
4011 status_i = 0;
4012
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004013 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004014 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004015 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004016 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004017 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004018 if (pid == -1)
4019 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004020 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004021 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004022}
4023
Tim Petersab034fa2002-02-01 11:27:43 +00004024#elif defined(HAVE_CWAIT)
4025
4026/* MS C has a variant of waitpid() that's usable for most purposes. */
4027static char posix_waitpid__doc__[] =
4028"waitpid(pid, options) -> (pid, status << 8)\n"
4029"Wait for completion of a given process. options is ignored on Windows.";
4030
4031static PyObject *
4032posix_waitpid(PyObject *self, PyObject *args)
4033{
4034 int pid, options;
4035 int status;
4036
4037 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4038 return NULL;
4039 Py_BEGIN_ALLOW_THREADS
4040 pid = _cwait(&status, pid, options);
4041 Py_END_ALLOW_THREADS
4042 if (pid == -1)
4043 return posix_error();
4044 else
4045 /* shift the status left a byte so this is more like the
4046 POSIX waitpid */
4047 return Py_BuildValue("ii", pid, status << 8);
4048}
4049#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004050
Guido van Rossumad0ee831995-03-01 10:34:45 +00004051#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004052static char posix_wait__doc__[] =
4053"wait() -> (pid, status)\n\
4054Wait for completion of a child process.";
4055
Barry Warsaw53699e91996-12-10 23:23:01 +00004056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004057posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004058{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004059 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004060#ifdef UNION_WAIT
4061 union wait status;
4062#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004063#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004064 int status;
4065#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004066#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004067 if (!PyArg_ParseTuple(args, ":wait"))
4068 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004069 status_i = 0;
4070 Py_BEGIN_ALLOW_THREADS
4071 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004072 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004073 if (pid == -1)
4074 return posix_error();
4075 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004076 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004077#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004078}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004079#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004080
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004081
4082static char posix_lstat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00004083"lstat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
4084 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004085Like stat(path), but do not follow symbolic links.";
4086
Barry Warsaw53699e91996-12-10 23:23:01 +00004087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004088posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004089{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004090#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004091 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004092#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004093 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004094#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004095}
4096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004097
Guido van Rossumb6775db1994-08-01 11:34:53 +00004098#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004099static char posix_readlink__doc__[] =
4100"readlink(path) -> path\n\
4101Return a string representing the path to which the symbolic link points.";
4102
Barry Warsaw53699e91996-12-10 23:23:01 +00004103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004104posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004105{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004106 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004107 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004108 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004109 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004110 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004111 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004112 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004113 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004114 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004115 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004116 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004117}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004118#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004120
Guido van Rossumb6775db1994-08-01 11:34:53 +00004121#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004122static char posix_symlink__doc__[] =
4123"symlink(src, dst) -> None\n\
4124Create a symbolic link.";
4125
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004127posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004128{
Mark Hammondef8b6542001-05-13 08:04:26 +00004129 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004130}
4131#endif /* HAVE_SYMLINK */
4132
4133
4134#ifdef HAVE_TIMES
4135#ifndef HZ
4136#define HZ 60 /* Universal constant :-) */
4137#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004138
Guido van Rossumd48f2521997-12-05 22:19:34 +00004139#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4140static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004141system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004142{
4143 ULONG value = 0;
4144
4145 Py_BEGIN_ALLOW_THREADS
4146 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4147 Py_END_ALLOW_THREADS
4148
4149 return value;
4150}
4151
4152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004153posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004154{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004155 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004156 return NULL;
4157
4158 /* Currently Only Uptime is Provided -- Others Later */
4159 return Py_BuildValue("ddddd",
4160 (double)0 /* t.tms_utime / HZ */,
4161 (double)0 /* t.tms_stime / HZ */,
4162 (double)0 /* t.tms_cutime / HZ */,
4163 (double)0 /* t.tms_cstime / HZ */,
4164 (double)system_uptime() / 1000);
4165}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004166#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004167static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004168posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004169{
4170 struct tms t;
4171 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004172 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004173 return NULL;
4174 errno = 0;
4175 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004176 if (c == (clock_t) -1)
4177 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004178 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004179 (double)t.tms_utime / HZ,
4180 (double)t.tms_stime / HZ,
4181 (double)t.tms_cutime / HZ,
4182 (double)t.tms_cstime / HZ,
4183 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004184}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004185#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004186#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004187
4188
Guido van Rossum87755a21996-09-07 00:59:43 +00004189#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004190#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004192posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004193{
4194 FILETIME create, exit, kernel, user;
4195 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004196 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004197 return NULL;
4198 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004199 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4200 /* The fields of a FILETIME structure are the hi and lo part
4201 of a 64-bit value expressed in 100 nanosecond units.
4202 1e7 is one second in such units; 1e-7 the inverse.
4203 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4204 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004205 return Py_BuildValue(
4206 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004207 (double)(kernel.dwHighDateTime*429.4967296 +
4208 kernel.dwLowDateTime*1e-7),
4209 (double)(user.dwHighDateTime*429.4967296 +
4210 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004211 (double)0,
4212 (double)0,
4213 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004214}
Guido van Rossum8d665e61996-06-26 18:22:49 +00004215#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004216
4217#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00004218static char posix_times__doc__[] =
4219"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
4220Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004221#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004223
Guido van Rossumb6775db1994-08-01 11:34:53 +00004224#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004225static char posix_setsid__doc__[] =
4226"setsid() -> None\n\
4227Call the system call setsid().";
4228
Barry Warsaw53699e91996-12-10 23:23:01 +00004229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004230posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004231{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004232 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004233 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004234 if (setsid() < 0)
4235 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004236 Py_INCREF(Py_None);
4237 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004238}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004239#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004240
Guido van Rossumb6775db1994-08-01 11:34:53 +00004241#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004242static char posix_setpgid__doc__[] =
4243"setpgid(pid, pgrp) -> None\n\
4244Call the system call setpgid().";
4245
Barry Warsaw53699e91996-12-10 23:23:01 +00004246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004247posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004248{
4249 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004250 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004251 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004252 if (setpgid(pid, pgrp) < 0)
4253 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004254 Py_INCREF(Py_None);
4255 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004256}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004257#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004258
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004259
Guido van Rossumb6775db1994-08-01 11:34:53 +00004260#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004261static char posix_tcgetpgrp__doc__[] =
4262"tcgetpgrp(fd) -> pgid\n\
4263Return the process group associated with the terminal given by a fd.";
4264
Barry Warsaw53699e91996-12-10 23:23:01 +00004265static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004266posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004267{
4268 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004269 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004270 return NULL;
4271 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004272 if (pgid < 0)
4273 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004274 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004275}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004276#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004278
Guido van Rossumb6775db1994-08-01 11:34:53 +00004279#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004280static char posix_tcsetpgrp__doc__[] =
4281"tcsetpgrp(fd, pgid) -> None\n\
4282Set the process group associated with the terminal given by a fd.";
4283
Barry Warsaw53699e91996-12-10 23:23:01 +00004284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004285posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004286{
4287 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004288 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004289 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004290 if (tcsetpgrp(fd, pgid) < 0)
4291 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004292 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004293 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004294}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004295#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004296
Guido van Rossum687dd131993-05-17 08:34:16 +00004297/* Functions acting on file descriptors */
4298
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004299static char posix_open__doc__[] =
4300"open(filename, flag [, mode=0777]) -> fd\n\
4301Open a file (for low level IO).";
4302
Barry Warsaw53699e91996-12-10 23:23:01 +00004303static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004304posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004305{
Mark Hammondef8b6542001-05-13 08:04:26 +00004306 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004307 int flag;
4308 int mode = 0777;
4309 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004310 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004311 Py_FileSystemDefaultEncoding, &file,
4312 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004313 return NULL;
4314
Barry Warsaw53699e91996-12-10 23:23:01 +00004315 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004316 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004317 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004318 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004319 return posix_error_with_allocated_filename(file);
4320 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004321 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004322}
4323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004324
4325static char posix_close__doc__[] =
4326"close(fd) -> None\n\
4327Close a file descriptor (for low level IO).";
4328
Barry Warsaw53699e91996-12-10 23:23:01 +00004329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004330posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004331{
4332 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004333 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004334 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004335 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004336 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004337 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004338 if (res < 0)
4339 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004340 Py_INCREF(Py_None);
4341 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004342}
4343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004344
4345static char posix_dup__doc__[] =
4346"dup(fd) -> fd2\n\
4347Return a duplicate of a file descriptor.";
4348
Barry Warsaw53699e91996-12-10 23:23:01 +00004349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004350posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004351{
4352 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004353 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004354 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004355 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004356 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004357 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004358 if (fd < 0)
4359 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004360 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004361}
4362
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004363
4364static char posix_dup2__doc__[] =
4365"dup2(fd, fd2) -> None\n\
4366Duplicate file descriptor.";
4367
Barry Warsaw53699e91996-12-10 23:23:01 +00004368static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004369posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004370{
4371 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004372 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004373 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004374 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004375 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004376 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004377 if (res < 0)
4378 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004379 Py_INCREF(Py_None);
4380 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004381}
4382
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004383
4384static char posix_lseek__doc__[] =
4385"lseek(fd, pos, how) -> newpos\n\
4386Set the current position of a file descriptor.";
4387
Barry Warsaw53699e91996-12-10 23:23:01 +00004388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004389posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004390{
4391 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00004392#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004393 LONG_LONG pos, res;
4394#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004395 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004396#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004397 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004398 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004399 return NULL;
4400#ifdef SEEK_SET
4401 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4402 switch (how) {
4403 case 0: how = SEEK_SET; break;
4404 case 1: how = SEEK_CUR; break;
4405 case 2: how = SEEK_END; break;
4406 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004407#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004408
4409#if !defined(HAVE_LARGEFILE_SUPPORT)
4410 pos = PyInt_AsLong(posobj);
4411#else
4412 pos = PyLong_Check(posobj) ?
4413 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4414#endif
4415 if (PyErr_Occurred())
4416 return NULL;
4417
Barry Warsaw53699e91996-12-10 23:23:01 +00004418 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00004419#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004420 res = _lseeki64(fd, pos, how);
4421#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004422 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004423#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004424 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004425 if (res < 0)
4426 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004427
4428#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004429 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004430#else
4431 return PyLong_FromLongLong(res);
4432#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004433}
4434
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004435
4436static char posix_read__doc__[] =
4437"read(fd, buffersize) -> string\n\
4438Read a file descriptor.";
4439
Barry Warsaw53699e91996-12-10 23:23:01 +00004440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004441posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004442{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004443 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004444 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004445 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004446 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004447 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004448 if (buffer == NULL)
4449 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004450 Py_BEGIN_ALLOW_THREADS
4451 n = read(fd, PyString_AsString(buffer), size);
4452 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004453 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004454 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004455 return posix_error();
4456 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004457 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004458 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004459 return buffer;
4460}
4461
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004462
4463static char posix_write__doc__[] =
4464"write(fd, string) -> byteswritten\n\
4465Write a string to a file descriptor.";
4466
Barry Warsaw53699e91996-12-10 23:23:01 +00004467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004468posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004469{
4470 int fd, size;
4471 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004472 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004473 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004474 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004475 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004476 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004477 if (size < 0)
4478 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004479 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004480}
4481
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004482
4483static char posix_fstat__doc__[]=
4484"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
4485Like stat(), but for an open file descriptor.";
4486
Barry Warsaw53699e91996-12-10 23:23:01 +00004487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004488posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004489{
4490 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004491 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004492 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004493 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004494 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004495 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004496 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004497 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004498 if (res != 0)
4499 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004500
Fred Drake699f3522000-06-29 21:12:41 +00004501 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004502}
4503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004504
4505static char posix_fdopen__doc__[] =
4506"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
4507Return an open file object connected to a file descriptor.";
4508
Barry Warsaw53699e91996-12-10 23:23:01 +00004509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004510posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004511{
Guido van Rossum687dd131993-05-17 08:34:16 +00004512 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004513 char *mode = "r";
4514 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004515 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004516 PyObject *f;
4517 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004518 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004519
Barry Warsaw53699e91996-12-10 23:23:01 +00004520 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004521 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004522 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004523 if (fp == NULL)
4524 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004525 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004526 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004527 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004528 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004529}
4530
Skip Montanaro1517d842000-07-19 14:34:14 +00004531static char posix_isatty__doc__[] =
Fred Drake106c1a02002-04-23 15:58:02 +00004532"isatty(fd) -> bool\n\
4533Return True if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00004534connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00004535
4536static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004537posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004538{
4539 int fd;
4540 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4541 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004542 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004543}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004544
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004545#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004546static char posix_pipe__doc__[] =
4547"pipe() -> (read_end, write_end)\n\
4548Create a pipe.";
4549
Barry Warsaw53699e91996-12-10 23:23:01 +00004550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004551posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004552{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004553#if defined(PYOS_OS2)
4554 HFILE read, write;
4555 APIRET rc;
4556
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004557 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004558 return NULL;
4559
4560 Py_BEGIN_ALLOW_THREADS
4561 rc = DosCreatePipe( &read, &write, 4096);
4562 Py_END_ALLOW_THREADS
4563 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004564 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004565
4566 return Py_BuildValue("(ii)", read, write);
4567#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00004568#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00004569 int fds[2];
4570 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004571 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004572 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004573 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004574 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004575 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004576 if (res != 0)
4577 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004578 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004579#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00004580 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004581 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004582 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004583 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004584 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004585 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004586 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004587 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004588 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004589 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004590 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4591 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004592 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004593#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004594#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004595}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004596#endif /* HAVE_PIPE */
4597
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004598
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004599#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004600static char posix_mkfifo__doc__[] =
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004601"mkfifo(filename, [, mode=0666]) -> None\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004602Create a FIFO (a POSIX named pipe).";
4603
Barry Warsaw53699e91996-12-10 23:23:01 +00004604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004605posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004606{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004607 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004608 int mode = 0666;
4609 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004610 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004611 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004612 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004613 res = mkfifo(filename, mode);
4614 Py_END_ALLOW_THREADS
4615 if (res < 0)
4616 return posix_error();
4617 Py_INCREF(Py_None);
4618 return Py_None;
4619}
4620#endif
4621
4622
4623#ifdef HAVE_MKNOD
4624static char posix_mknod__doc__[] =
4625"mknod(filename, [, mode=0600, major, minor]) -> None\n\
4626Create a filesystem node (file, device special file or named pipe)\n\
4627named filename. mode specifies both the permissions to use and the\n\
4628type of node to be created, being combined (bitwise OR) with one of\n\
4629S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4630major and minor define the newly created device special file, otherwise\n\
4631they are ignored.";
4632
4633
4634static PyObject *
4635posix_mknod(PyObject *self, PyObject *args)
4636{
4637 char *filename;
4638 int mode = 0600;
4639 int major = 0;
4640 int minor = 0;
4641 int res;
4642 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4643 &mode, &major, &minor))
4644 return NULL;
4645 Py_BEGIN_ALLOW_THREADS
4646 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004647 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004648 if (res < 0)
4649 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004650 Py_INCREF(Py_None);
4651 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004652}
4653#endif
4654
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004655
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004656#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004657static char posix_ftruncate__doc__[] =
4658"ftruncate(fd, length) -> None\n\
4659Truncate a file to a specified length.";
4660
Barry Warsaw53699e91996-12-10 23:23:01 +00004661static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004662posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004663{
4664 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004665 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004666 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004667 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004668
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004669 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004670 return NULL;
4671
4672#if !defined(HAVE_LARGEFILE_SUPPORT)
4673 length = PyInt_AsLong(lenobj);
4674#else
4675 length = PyLong_Check(lenobj) ?
4676 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4677#endif
4678 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004679 return NULL;
4680
Barry Warsaw53699e91996-12-10 23:23:01 +00004681 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004682 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004683 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004684 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004685 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004686 return NULL;
4687 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004688 Py_INCREF(Py_None);
4689 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004690}
4691#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004692
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004693#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004694static char posix_putenv__doc__[] =
4695"putenv(key, value) -> None\n\
4696Change or add an environment variable.";
4697
Fred Drake762e2061999-08-26 17:23:54 +00004698/* Save putenv() parameters as values here, so we can collect them when they
4699 * get re-set with another call for the same key. */
4700static PyObject *posix_putenv_garbage;
4701
Tim Peters5aa91602002-01-30 05:46:57 +00004702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004703posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004704{
4705 char *s1, *s2;
4706 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004707 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004708 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004709
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004710 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004711 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004712
4713#if defined(PYOS_OS2)
4714 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4715 APIRET rc;
4716
4717 if (strlen(s2) == 0) /* If New Value is an Empty String */
4718 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4719
4720 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4721 if (rc != NO_ERROR)
4722 return os2_error(rc);
4723
4724 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4725 APIRET rc;
4726
4727 if (strlen(s2) == 0) /* If New Value is an Empty String */
4728 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4729
4730 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4731 if (rc != NO_ERROR)
4732 return os2_error(rc);
4733 } else {
4734#endif
4735
Fred Drake762e2061999-08-26 17:23:54 +00004736 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004737 len = strlen(s1) + strlen(s2) + 2;
4738 /* len includes space for a trailing \0; the size arg to
4739 PyString_FromStringAndSize does not count that */
4740 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004741 if (newstr == NULL)
4742 return PyErr_NoMemory();
4743 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004744 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004745 if (putenv(new)) {
4746 posix_error();
4747 return NULL;
4748 }
Fred Drake762e2061999-08-26 17:23:54 +00004749 /* Install the first arg and newstr in posix_putenv_garbage;
4750 * this will cause previous value to be collected. This has to
4751 * happen after the real putenv() call because the old value
4752 * was still accessible until then. */
4753 if (PyDict_SetItem(posix_putenv_garbage,
4754 PyTuple_GET_ITEM(args, 0), newstr)) {
4755 /* really not much we can do; just leak */
4756 PyErr_Clear();
4757 }
4758 else {
4759 Py_DECREF(newstr);
4760 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004761
4762#if defined(PYOS_OS2)
4763 }
4764#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004765 Py_INCREF(Py_None);
4766 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004767}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004768#endif /* putenv */
4769
Guido van Rossumc524d952001-10-19 01:31:59 +00004770#ifdef HAVE_UNSETENV
4771static char posix_unsetenv__doc__[] =
4772"unsetenv(key) -> None\n\
4773Delete an environment variable.";
4774
4775static PyObject *
4776posix_unsetenv(PyObject *self, PyObject *args)
4777{
4778 char *s1;
4779
4780 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4781 return NULL;
4782
4783 unsetenv(s1);
4784
4785 /* Remove the key from posix_putenv_garbage;
4786 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004787 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004788 * old value was still accessible until then.
4789 */
4790 if (PyDict_DelItem(posix_putenv_garbage,
4791 PyTuple_GET_ITEM(args, 0))) {
4792 /* really not much we can do; just leak */
4793 PyErr_Clear();
4794 }
4795
4796 Py_INCREF(Py_None);
4797 return Py_None;
4798}
4799#endif /* unsetenv */
4800
Guido van Rossumb6a47161997-09-15 22:54:34 +00004801#ifdef HAVE_STRERROR
4802static char posix_strerror__doc__[] =
4803"strerror(code) -> string\n\
4804Translate an error code to a message string.";
4805
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004807posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004808{
4809 int code;
4810 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004811 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004812 return NULL;
4813 message = strerror(code);
4814 if (message == NULL) {
4815 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004816 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004817 return NULL;
4818 }
4819 return PyString_FromString(message);
4820}
4821#endif /* strerror */
4822
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004823
Guido van Rossumc9641791998-08-04 15:26:23 +00004824#ifdef HAVE_SYS_WAIT_H
4825
Fred Drake106c1a02002-04-23 15:58:02 +00004826#ifdef WCOREDUMP
4827static char posix_WCOREDUMP__doc__[] =
4828"WCOREDUMP(status) -> bool\n\
4829Return True if the process returning 'status' was dumped to a core file.";
4830
4831static PyObject *
4832posix_WCOREDUMP(PyObject *self, PyObject *args)
4833{
4834#ifdef UNION_WAIT
4835 union wait status;
4836#define status_i (status.w_status)
4837#else
4838 int status;
4839#define status_i status
4840#endif
4841 status_i = 0;
4842
4843 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4844 {
4845 return NULL;
4846 }
4847
4848 return PyBool_FromLong(WCOREDUMP(status));
4849#undef status_i
4850}
4851#endif /* WCOREDUMP */
4852
4853#ifdef WIFCONTINUED
4854static char posix_WIFCONTINUED__doc__[] =
4855"WIFCONTINUED(status) -> bool\n\
4856Return True if the process returning 'status' was continued from a\n\
4857job control stop.";
4858
4859static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004860posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004861{
4862#ifdef UNION_WAIT
4863 union wait status;
4864#define status_i (status.w_status)
4865#else
4866 int status;
4867#define status_i status
4868#endif
4869 status_i = 0;
4870
4871 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4872 {
4873 return NULL;
4874 }
4875
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004876 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004877#undef status_i
4878}
4879#endif /* WIFCONTINUED */
4880
Guido van Rossumc9641791998-08-04 15:26:23 +00004881#ifdef WIFSTOPPED
4882static char posix_WIFSTOPPED__doc__[] =
Fred Drake106c1a02002-04-23 15:58:02 +00004883"WIFSTOPPED(status) -> bool\n\
4884Return True if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004885
4886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004887posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004888{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004889#ifdef UNION_WAIT
4890 union wait status;
4891#define status_i (status.w_status)
4892#else
4893 int status;
4894#define status_i status
4895#endif
4896 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004897
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004898 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004899 {
4900 return NULL;
4901 }
Tim Peters5aa91602002-01-30 05:46:57 +00004902
Fred Drake106c1a02002-04-23 15:58:02 +00004903 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004904#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004905}
4906#endif /* WIFSTOPPED */
4907
4908#ifdef WIFSIGNALED
4909static char posix_WIFSIGNALED__doc__[] =
Fred Drake106c1a02002-04-23 15:58:02 +00004910"WIFSIGNALED(status) -> bool\n\
4911Return True if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004912
4913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004914posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004915{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004916#ifdef UNION_WAIT
4917 union wait status;
4918#define status_i (status.w_status)
4919#else
4920 int status;
4921#define status_i status
4922#endif
4923 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004924
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004925 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004926 {
4927 return NULL;
4928 }
Tim Peters5aa91602002-01-30 05:46:57 +00004929
Fred Drake106c1a02002-04-23 15:58:02 +00004930 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004931#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004932}
4933#endif /* WIFSIGNALED */
4934
4935#ifdef WIFEXITED
4936static char posix_WIFEXITED__doc__[] =
Fred Drake106c1a02002-04-23 15:58:02 +00004937"WIFEXITED(status) -> bool\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004938Return true if the process returning 'status' exited using the exit()\n\
4939system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004940
4941static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004942posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004943{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004944#ifdef UNION_WAIT
4945 union wait status;
4946#define status_i (status.w_status)
4947#else
4948 int status;
4949#define status_i status
4950#endif
4951 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004952
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004953 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004954 {
4955 return NULL;
4956 }
Tim Peters5aa91602002-01-30 05:46:57 +00004957
Fred Drake106c1a02002-04-23 15:58:02 +00004958 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004959#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004960}
4961#endif /* WIFEXITED */
4962
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004963#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004964static char posix_WEXITSTATUS__doc__[] =
4965"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004966Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004967
4968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004969posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004970{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004971#ifdef UNION_WAIT
4972 union wait status;
4973#define status_i (status.w_status)
4974#else
4975 int status;
4976#define status_i status
4977#endif
4978 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004979
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004980 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004981 {
4982 return NULL;
4983 }
Tim Peters5aa91602002-01-30 05:46:57 +00004984
Guido van Rossumc9641791998-08-04 15:26:23 +00004985 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004986#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004987}
4988#endif /* WEXITSTATUS */
4989
4990#ifdef WTERMSIG
4991static char posix_WTERMSIG__doc__[] =
4992"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004993Return the signal that terminated the process that provided the 'status'\n\
4994value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004995
4996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004997posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004998{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004999#ifdef UNION_WAIT
5000 union wait status;
5001#define status_i (status.w_status)
5002#else
5003 int status;
5004#define status_i status
5005#endif
5006 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005007
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005008 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005009 {
5010 return NULL;
5011 }
Tim Peters5aa91602002-01-30 05:46:57 +00005012
Guido van Rossumc9641791998-08-04 15:26:23 +00005013 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005014#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005015}
5016#endif /* WTERMSIG */
5017
5018#ifdef WSTOPSIG
5019static char posix_WSTOPSIG__doc__[] =
5020"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005021Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00005022
5023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005024posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005025{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005026#ifdef UNION_WAIT
5027 union wait status;
5028#define status_i (status.w_status)
5029#else
5030 int status;
5031#define status_i status
5032#endif
5033 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005034
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005035 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005036 {
5037 return NULL;
5038 }
Tim Peters5aa91602002-01-30 05:46:57 +00005039
Guido van Rossumc9641791998-08-04 15:26:23 +00005040 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005041#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005042}
5043#endif /* WSTOPSIG */
5044
5045#endif /* HAVE_SYS_WAIT_H */
5046
5047
Guido van Rossum94f6f721999-01-06 18:42:14 +00005048#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005049#ifdef _SCO_DS
5050/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5051 needed definitions in sys/statvfs.h */
5052#define _SVID3
5053#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005054#include <sys/statvfs.h>
5055
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005056static PyObject*
5057_pystatvfs_fromstructstatvfs(struct statvfs st) {
5058 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5059 if (v == NULL)
5060 return NULL;
5061
5062#if !defined(HAVE_LARGEFILE_SUPPORT)
5063 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5064 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5065 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5066 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5067 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5068 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5069 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5070 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5071 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5072 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5073#else
5074 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5075 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005076 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005077 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005078 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005079 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5080 PyStructSequence_SET_ITEM(v, 4,
5081 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005082 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005083 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005084 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005085 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005086 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005087 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5088 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5089 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5090#endif
5091
5092 return v;
5093}
5094
Guido van Rossum94f6f721999-01-06 18:42:14 +00005095static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005096"fstatvfs(fd) -> \n\
5097 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005098Perform an fstatvfs system call on the given fd.";
5099
5100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005101posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005102{
5103 int fd, res;
5104 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005105
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005106 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005107 return NULL;
5108 Py_BEGIN_ALLOW_THREADS
5109 res = fstatvfs(fd, &st);
5110 Py_END_ALLOW_THREADS
5111 if (res != 0)
5112 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005113
5114 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005115}
5116#endif /* HAVE_FSTATVFS */
5117
5118
5119#if defined(HAVE_STATVFS)
5120#include <sys/statvfs.h>
5121
5122static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005123"statvfs(path) -> \n\
5124 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005125Perform a statvfs system call on the given path.";
5126
5127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005128posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005129{
5130 char *path;
5131 int res;
5132 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005133 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005134 return NULL;
5135 Py_BEGIN_ALLOW_THREADS
5136 res = statvfs(path, &st);
5137 Py_END_ALLOW_THREADS
5138 if (res != 0)
5139 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005140
5141 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005142}
5143#endif /* HAVE_STATVFS */
5144
5145
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005146#ifdef HAVE_TEMPNAM
5147static char posix_tempnam__doc__[] = "\
5148tempnam([dir[, prefix]]) -> string\n\
5149Return a unique name for a temporary file.\n\
5150The directory and a short may be specified as strings; they may be omitted\n\
5151or None if not needed.";
5152
5153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005154posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005155{
5156 PyObject *result = NULL;
5157 char *dir = NULL;
5158 char *pfx = NULL;
5159 char *name;
5160
5161 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5162 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005163
5164 if (PyErr_Warn(PyExc_RuntimeWarning,
5165 "tempnam is a potential security risk to your program") < 0)
5166 return NULL;
5167
Fred Drake78b71c22001-07-17 20:37:36 +00005168#ifdef MS_WIN32
5169 name = _tempnam(dir, pfx);
5170#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005171 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005172#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005173 if (name == NULL)
5174 return PyErr_NoMemory();
5175 result = PyString_FromString(name);
5176 free(name);
5177 return result;
5178}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005179#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005180
5181
5182#ifdef HAVE_TMPFILE
5183static char posix_tmpfile__doc__[] = "\
5184tmpfile() -> file object\n\
5185Create a temporary file with no directory entries.";
5186
5187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005188posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005189{
5190 FILE *fp;
5191
5192 if (!PyArg_ParseTuple(args, ":tmpfile"))
5193 return NULL;
5194 fp = tmpfile();
5195 if (fp == NULL)
5196 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005197 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005198}
5199#endif
5200
5201
5202#ifdef HAVE_TMPNAM
5203static char posix_tmpnam__doc__[] = "\
5204tmpnam() -> string\n\
5205Return a unique name for a temporary file.";
5206
5207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005208posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005209{
5210 char buffer[L_tmpnam];
5211 char *name;
5212
5213 if (!PyArg_ParseTuple(args, ":tmpnam"))
5214 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005215
5216 if (PyErr_Warn(PyExc_RuntimeWarning,
5217 "tmpnam is a potential security risk to your program") < 0)
5218 return NULL;
5219
Greg Wardb48bc172000-03-01 21:51:56 +00005220#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005221 name = tmpnam_r(buffer);
5222#else
5223 name = tmpnam(buffer);
5224#endif
5225 if (name == NULL) {
5226 PyErr_SetObject(PyExc_OSError,
5227 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005228#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005229 "unexpected NULL from tmpnam_r"
5230#else
5231 "unexpected NULL from tmpnam"
5232#endif
5233 ));
5234 return NULL;
5235 }
5236 return PyString_FromString(buffer);
5237}
5238#endif
5239
5240
Fred Drakec9680921999-12-13 16:37:25 +00005241/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5242 * It maps strings representing configuration variable names to
5243 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005244 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005245 * rarely-used constants. There are three separate tables that use
5246 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005247 *
5248 * This code is always included, even if none of the interfaces that
5249 * need it are included. The #if hackery needed to avoid it would be
5250 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005251 */
5252struct constdef {
5253 char *name;
5254 long value;
5255};
5256
Fred Drake12c6e2d1999-12-14 21:25:03 +00005257static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005258conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5259 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005260{
5261 if (PyInt_Check(arg)) {
5262 *valuep = PyInt_AS_LONG(arg);
5263 return 1;
5264 }
5265 if (PyString_Check(arg)) {
5266 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005267 size_t lo = 0;
5268 size_t mid;
5269 size_t hi = tablesize;
5270 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005271 char *confname = PyString_AS_STRING(arg);
5272 while (lo < hi) {
5273 mid = (lo + hi) / 2;
5274 cmp = strcmp(confname, table[mid].name);
5275 if (cmp < 0)
5276 hi = mid;
5277 else if (cmp > 0)
5278 lo = mid + 1;
5279 else {
5280 *valuep = table[mid].value;
5281 return 1;
5282 }
5283 }
5284 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5285 }
5286 else
5287 PyErr_SetString(PyExc_TypeError,
5288 "configuration names must be strings or integers");
5289 return 0;
5290}
5291
5292
5293#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5294static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005295#ifdef _PC_ABI_AIO_XFER_MAX
5296 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5297#endif
5298#ifdef _PC_ABI_ASYNC_IO
5299 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5300#endif
Fred Drakec9680921999-12-13 16:37:25 +00005301#ifdef _PC_ASYNC_IO
5302 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5303#endif
5304#ifdef _PC_CHOWN_RESTRICTED
5305 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5306#endif
5307#ifdef _PC_FILESIZEBITS
5308 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5309#endif
5310#ifdef _PC_LAST
5311 {"PC_LAST", _PC_LAST},
5312#endif
5313#ifdef _PC_LINK_MAX
5314 {"PC_LINK_MAX", _PC_LINK_MAX},
5315#endif
5316#ifdef _PC_MAX_CANON
5317 {"PC_MAX_CANON", _PC_MAX_CANON},
5318#endif
5319#ifdef _PC_MAX_INPUT
5320 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5321#endif
5322#ifdef _PC_NAME_MAX
5323 {"PC_NAME_MAX", _PC_NAME_MAX},
5324#endif
5325#ifdef _PC_NO_TRUNC
5326 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5327#endif
5328#ifdef _PC_PATH_MAX
5329 {"PC_PATH_MAX", _PC_PATH_MAX},
5330#endif
5331#ifdef _PC_PIPE_BUF
5332 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5333#endif
5334#ifdef _PC_PRIO_IO
5335 {"PC_PRIO_IO", _PC_PRIO_IO},
5336#endif
5337#ifdef _PC_SOCK_MAXBUF
5338 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5339#endif
5340#ifdef _PC_SYNC_IO
5341 {"PC_SYNC_IO", _PC_SYNC_IO},
5342#endif
5343#ifdef _PC_VDISABLE
5344 {"PC_VDISABLE", _PC_VDISABLE},
5345#endif
5346};
5347
Fred Drakec9680921999-12-13 16:37:25 +00005348static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005349conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005350{
5351 return conv_confname(arg, valuep, posix_constants_pathconf,
5352 sizeof(posix_constants_pathconf)
5353 / sizeof(struct constdef));
5354}
5355#endif
5356
5357#ifdef HAVE_FPATHCONF
5358static char posix_fpathconf__doc__[] = "\
5359fpathconf(fd, name) -> integer\n\
5360Return the configuration limit name for the file descriptor fd.\n\
5361If there is no limit, return -1.";
5362
5363static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005364posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005365{
5366 PyObject *result = NULL;
5367 int name, fd;
5368
Fred Drake12c6e2d1999-12-14 21:25:03 +00005369 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5370 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005371 long limit;
5372
5373 errno = 0;
5374 limit = fpathconf(fd, name);
5375 if (limit == -1 && errno != 0)
5376 posix_error();
5377 else
5378 result = PyInt_FromLong(limit);
5379 }
5380 return result;
5381}
5382#endif
5383
5384
5385#ifdef HAVE_PATHCONF
5386static char posix_pathconf__doc__[] = "\
5387pathconf(path, name) -> integer\n\
5388Return the configuration limit name for the file or directory path.\n\
5389If there is no limit, return -1.";
5390
5391static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005392posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005393{
5394 PyObject *result = NULL;
5395 int name;
5396 char *path;
5397
5398 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5399 conv_path_confname, &name)) {
5400 long limit;
5401
5402 errno = 0;
5403 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005404 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005405 if (errno == EINVAL)
5406 /* could be a path or name problem */
5407 posix_error();
5408 else
5409 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005410 }
Fred Drakec9680921999-12-13 16:37:25 +00005411 else
5412 result = PyInt_FromLong(limit);
5413 }
5414 return result;
5415}
5416#endif
5417
5418#ifdef HAVE_CONFSTR
5419static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005420#ifdef _CS_ARCHITECTURE
5421 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5422#endif
5423#ifdef _CS_HOSTNAME
5424 {"CS_HOSTNAME", _CS_HOSTNAME},
5425#endif
5426#ifdef _CS_HW_PROVIDER
5427 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5428#endif
5429#ifdef _CS_HW_SERIAL
5430 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5431#endif
5432#ifdef _CS_INITTAB_NAME
5433 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5434#endif
Fred Drakec9680921999-12-13 16:37:25 +00005435#ifdef _CS_LFS64_CFLAGS
5436 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5437#endif
5438#ifdef _CS_LFS64_LDFLAGS
5439 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5440#endif
5441#ifdef _CS_LFS64_LIBS
5442 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5443#endif
5444#ifdef _CS_LFS64_LINTFLAGS
5445 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5446#endif
5447#ifdef _CS_LFS_CFLAGS
5448 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5449#endif
5450#ifdef _CS_LFS_LDFLAGS
5451 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5452#endif
5453#ifdef _CS_LFS_LIBS
5454 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5455#endif
5456#ifdef _CS_LFS_LINTFLAGS
5457 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5458#endif
Fred Draked86ed291999-12-15 15:34:33 +00005459#ifdef _CS_MACHINE
5460 {"CS_MACHINE", _CS_MACHINE},
5461#endif
Fred Drakec9680921999-12-13 16:37:25 +00005462#ifdef _CS_PATH
5463 {"CS_PATH", _CS_PATH},
5464#endif
Fred Draked86ed291999-12-15 15:34:33 +00005465#ifdef _CS_RELEASE
5466 {"CS_RELEASE", _CS_RELEASE},
5467#endif
5468#ifdef _CS_SRPC_DOMAIN
5469 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5470#endif
5471#ifdef _CS_SYSNAME
5472 {"CS_SYSNAME", _CS_SYSNAME},
5473#endif
5474#ifdef _CS_VERSION
5475 {"CS_VERSION", _CS_VERSION},
5476#endif
Fred Drakec9680921999-12-13 16:37:25 +00005477#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5478 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5479#endif
5480#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5481 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5482#endif
5483#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5484 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5485#endif
5486#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5487 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5488#endif
5489#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5490 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5491#endif
5492#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5493 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5494#endif
5495#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5496 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5497#endif
5498#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5499 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5500#endif
5501#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5502 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5503#endif
5504#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5505 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5506#endif
5507#ifdef _CS_XBS5_LP64_OFF64_LIBS
5508 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5509#endif
5510#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5511 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5512#endif
5513#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5514 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5515#endif
5516#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5517 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5518#endif
5519#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5520 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5521#endif
5522#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5523 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5524#endif
Fred Draked86ed291999-12-15 15:34:33 +00005525#ifdef _MIPS_CS_AVAIL_PROCESSORS
5526 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5527#endif
5528#ifdef _MIPS_CS_BASE
5529 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5530#endif
5531#ifdef _MIPS_CS_HOSTID
5532 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5533#endif
5534#ifdef _MIPS_CS_HW_NAME
5535 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5536#endif
5537#ifdef _MIPS_CS_NUM_PROCESSORS
5538 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5539#endif
5540#ifdef _MIPS_CS_OSREL_MAJ
5541 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5542#endif
5543#ifdef _MIPS_CS_OSREL_MIN
5544 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5545#endif
5546#ifdef _MIPS_CS_OSREL_PATCH
5547 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5548#endif
5549#ifdef _MIPS_CS_OS_NAME
5550 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5551#endif
5552#ifdef _MIPS_CS_OS_PROVIDER
5553 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5554#endif
5555#ifdef _MIPS_CS_PROCESSORS
5556 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5557#endif
5558#ifdef _MIPS_CS_SERIAL
5559 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5560#endif
5561#ifdef _MIPS_CS_VENDOR
5562 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5563#endif
Fred Drakec9680921999-12-13 16:37:25 +00005564};
5565
5566static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005567conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005568{
5569 return conv_confname(arg, valuep, posix_constants_confstr,
5570 sizeof(posix_constants_confstr)
5571 / sizeof(struct constdef));
5572}
5573
5574static char posix_confstr__doc__[] = "\
5575confstr(name) -> string\n\
5576Return a string-valued system configuration variable.";
5577
5578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005579posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005580{
5581 PyObject *result = NULL;
5582 int name;
5583 char buffer[64];
5584
5585 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5586 int len = confstr(name, buffer, sizeof(buffer));
5587
Fred Drakec9680921999-12-13 16:37:25 +00005588 errno = 0;
5589 if (len == 0) {
5590 if (errno != 0)
5591 posix_error();
5592 else
5593 result = PyString_FromString("");
5594 }
5595 else {
5596 if (len >= sizeof(buffer)) {
5597 result = PyString_FromStringAndSize(NULL, len);
5598 if (result != NULL)
5599 confstr(name, PyString_AS_STRING(result), len+1);
5600 }
5601 else
5602 result = PyString_FromString(buffer);
5603 }
5604 }
5605 return result;
5606}
5607#endif
5608
5609
5610#ifdef HAVE_SYSCONF
5611static struct constdef posix_constants_sysconf[] = {
5612#ifdef _SC_2_CHAR_TERM
5613 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5614#endif
5615#ifdef _SC_2_C_BIND
5616 {"SC_2_C_BIND", _SC_2_C_BIND},
5617#endif
5618#ifdef _SC_2_C_DEV
5619 {"SC_2_C_DEV", _SC_2_C_DEV},
5620#endif
5621#ifdef _SC_2_C_VERSION
5622 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5623#endif
5624#ifdef _SC_2_FORT_DEV
5625 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5626#endif
5627#ifdef _SC_2_FORT_RUN
5628 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5629#endif
5630#ifdef _SC_2_LOCALEDEF
5631 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5632#endif
5633#ifdef _SC_2_SW_DEV
5634 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5635#endif
5636#ifdef _SC_2_UPE
5637 {"SC_2_UPE", _SC_2_UPE},
5638#endif
5639#ifdef _SC_2_VERSION
5640 {"SC_2_VERSION", _SC_2_VERSION},
5641#endif
Fred Draked86ed291999-12-15 15:34:33 +00005642#ifdef _SC_ABI_ASYNCHRONOUS_IO
5643 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5644#endif
5645#ifdef _SC_ACL
5646 {"SC_ACL", _SC_ACL},
5647#endif
Fred Drakec9680921999-12-13 16:37:25 +00005648#ifdef _SC_AIO_LISTIO_MAX
5649 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5650#endif
Fred Drakec9680921999-12-13 16:37:25 +00005651#ifdef _SC_AIO_MAX
5652 {"SC_AIO_MAX", _SC_AIO_MAX},
5653#endif
5654#ifdef _SC_AIO_PRIO_DELTA_MAX
5655 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5656#endif
5657#ifdef _SC_ARG_MAX
5658 {"SC_ARG_MAX", _SC_ARG_MAX},
5659#endif
5660#ifdef _SC_ASYNCHRONOUS_IO
5661 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5662#endif
5663#ifdef _SC_ATEXIT_MAX
5664 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5665#endif
Fred Draked86ed291999-12-15 15:34:33 +00005666#ifdef _SC_AUDIT
5667 {"SC_AUDIT", _SC_AUDIT},
5668#endif
Fred Drakec9680921999-12-13 16:37:25 +00005669#ifdef _SC_AVPHYS_PAGES
5670 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5671#endif
5672#ifdef _SC_BC_BASE_MAX
5673 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5674#endif
5675#ifdef _SC_BC_DIM_MAX
5676 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5677#endif
5678#ifdef _SC_BC_SCALE_MAX
5679 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5680#endif
5681#ifdef _SC_BC_STRING_MAX
5682 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5683#endif
Fred Draked86ed291999-12-15 15:34:33 +00005684#ifdef _SC_CAP
5685 {"SC_CAP", _SC_CAP},
5686#endif
Fred Drakec9680921999-12-13 16:37:25 +00005687#ifdef _SC_CHARCLASS_NAME_MAX
5688 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5689#endif
5690#ifdef _SC_CHAR_BIT
5691 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5692#endif
5693#ifdef _SC_CHAR_MAX
5694 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5695#endif
5696#ifdef _SC_CHAR_MIN
5697 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5698#endif
5699#ifdef _SC_CHILD_MAX
5700 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5701#endif
5702#ifdef _SC_CLK_TCK
5703 {"SC_CLK_TCK", _SC_CLK_TCK},
5704#endif
5705#ifdef _SC_COHER_BLKSZ
5706 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5707#endif
5708#ifdef _SC_COLL_WEIGHTS_MAX
5709 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5710#endif
5711#ifdef _SC_DCACHE_ASSOC
5712 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5713#endif
5714#ifdef _SC_DCACHE_BLKSZ
5715 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5716#endif
5717#ifdef _SC_DCACHE_LINESZ
5718 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5719#endif
5720#ifdef _SC_DCACHE_SZ
5721 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5722#endif
5723#ifdef _SC_DCACHE_TBLKSZ
5724 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5725#endif
5726#ifdef _SC_DELAYTIMER_MAX
5727 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5728#endif
5729#ifdef _SC_EQUIV_CLASS_MAX
5730 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5731#endif
5732#ifdef _SC_EXPR_NEST_MAX
5733 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5734#endif
5735#ifdef _SC_FSYNC
5736 {"SC_FSYNC", _SC_FSYNC},
5737#endif
5738#ifdef _SC_GETGR_R_SIZE_MAX
5739 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5740#endif
5741#ifdef _SC_GETPW_R_SIZE_MAX
5742 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5743#endif
5744#ifdef _SC_ICACHE_ASSOC
5745 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5746#endif
5747#ifdef _SC_ICACHE_BLKSZ
5748 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5749#endif
5750#ifdef _SC_ICACHE_LINESZ
5751 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5752#endif
5753#ifdef _SC_ICACHE_SZ
5754 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5755#endif
Fred Draked86ed291999-12-15 15:34:33 +00005756#ifdef _SC_INF
5757 {"SC_INF", _SC_INF},
5758#endif
Fred Drakec9680921999-12-13 16:37:25 +00005759#ifdef _SC_INT_MAX
5760 {"SC_INT_MAX", _SC_INT_MAX},
5761#endif
5762#ifdef _SC_INT_MIN
5763 {"SC_INT_MIN", _SC_INT_MIN},
5764#endif
5765#ifdef _SC_IOV_MAX
5766 {"SC_IOV_MAX", _SC_IOV_MAX},
5767#endif
Fred Draked86ed291999-12-15 15:34:33 +00005768#ifdef _SC_IP_SECOPTS
5769 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5770#endif
Fred Drakec9680921999-12-13 16:37:25 +00005771#ifdef _SC_JOB_CONTROL
5772 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5773#endif
Fred Draked86ed291999-12-15 15:34:33 +00005774#ifdef _SC_KERN_POINTERS
5775 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5776#endif
5777#ifdef _SC_KERN_SIM
5778 {"SC_KERN_SIM", _SC_KERN_SIM},
5779#endif
Fred Drakec9680921999-12-13 16:37:25 +00005780#ifdef _SC_LINE_MAX
5781 {"SC_LINE_MAX", _SC_LINE_MAX},
5782#endif
5783#ifdef _SC_LOGIN_NAME_MAX
5784 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5785#endif
5786#ifdef _SC_LOGNAME_MAX
5787 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5788#endif
5789#ifdef _SC_LONG_BIT
5790 {"SC_LONG_BIT", _SC_LONG_BIT},
5791#endif
Fred Draked86ed291999-12-15 15:34:33 +00005792#ifdef _SC_MAC
5793 {"SC_MAC", _SC_MAC},
5794#endif
Fred Drakec9680921999-12-13 16:37:25 +00005795#ifdef _SC_MAPPED_FILES
5796 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5797#endif
5798#ifdef _SC_MAXPID
5799 {"SC_MAXPID", _SC_MAXPID},
5800#endif
5801#ifdef _SC_MB_LEN_MAX
5802 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5803#endif
5804#ifdef _SC_MEMLOCK
5805 {"SC_MEMLOCK", _SC_MEMLOCK},
5806#endif
5807#ifdef _SC_MEMLOCK_RANGE
5808 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5809#endif
5810#ifdef _SC_MEMORY_PROTECTION
5811 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5812#endif
5813#ifdef _SC_MESSAGE_PASSING
5814 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5815#endif
Fred Draked86ed291999-12-15 15:34:33 +00005816#ifdef _SC_MMAP_FIXED_ALIGNMENT
5817 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5818#endif
Fred Drakec9680921999-12-13 16:37:25 +00005819#ifdef _SC_MQ_OPEN_MAX
5820 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5821#endif
5822#ifdef _SC_MQ_PRIO_MAX
5823 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5824#endif
Fred Draked86ed291999-12-15 15:34:33 +00005825#ifdef _SC_NACLS_MAX
5826 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5827#endif
Fred Drakec9680921999-12-13 16:37:25 +00005828#ifdef _SC_NGROUPS_MAX
5829 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5830#endif
5831#ifdef _SC_NL_ARGMAX
5832 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5833#endif
5834#ifdef _SC_NL_LANGMAX
5835 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5836#endif
5837#ifdef _SC_NL_MSGMAX
5838 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5839#endif
5840#ifdef _SC_NL_NMAX
5841 {"SC_NL_NMAX", _SC_NL_NMAX},
5842#endif
5843#ifdef _SC_NL_SETMAX
5844 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5845#endif
5846#ifdef _SC_NL_TEXTMAX
5847 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5848#endif
5849#ifdef _SC_NPROCESSORS_CONF
5850 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5851#endif
5852#ifdef _SC_NPROCESSORS_ONLN
5853 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5854#endif
Fred Draked86ed291999-12-15 15:34:33 +00005855#ifdef _SC_NPROC_CONF
5856 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5857#endif
5858#ifdef _SC_NPROC_ONLN
5859 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5860#endif
Fred Drakec9680921999-12-13 16:37:25 +00005861#ifdef _SC_NZERO
5862 {"SC_NZERO", _SC_NZERO},
5863#endif
5864#ifdef _SC_OPEN_MAX
5865 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5866#endif
5867#ifdef _SC_PAGESIZE
5868 {"SC_PAGESIZE", _SC_PAGESIZE},
5869#endif
5870#ifdef _SC_PAGE_SIZE
5871 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5872#endif
5873#ifdef _SC_PASS_MAX
5874 {"SC_PASS_MAX", _SC_PASS_MAX},
5875#endif
5876#ifdef _SC_PHYS_PAGES
5877 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5878#endif
5879#ifdef _SC_PII
5880 {"SC_PII", _SC_PII},
5881#endif
5882#ifdef _SC_PII_INTERNET
5883 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5884#endif
5885#ifdef _SC_PII_INTERNET_DGRAM
5886 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5887#endif
5888#ifdef _SC_PII_INTERNET_STREAM
5889 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5890#endif
5891#ifdef _SC_PII_OSI
5892 {"SC_PII_OSI", _SC_PII_OSI},
5893#endif
5894#ifdef _SC_PII_OSI_CLTS
5895 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5896#endif
5897#ifdef _SC_PII_OSI_COTS
5898 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5899#endif
5900#ifdef _SC_PII_OSI_M
5901 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5902#endif
5903#ifdef _SC_PII_SOCKET
5904 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5905#endif
5906#ifdef _SC_PII_XTI
5907 {"SC_PII_XTI", _SC_PII_XTI},
5908#endif
5909#ifdef _SC_POLL
5910 {"SC_POLL", _SC_POLL},
5911#endif
5912#ifdef _SC_PRIORITIZED_IO
5913 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5914#endif
5915#ifdef _SC_PRIORITY_SCHEDULING
5916 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5917#endif
5918#ifdef _SC_REALTIME_SIGNALS
5919 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5920#endif
5921#ifdef _SC_RE_DUP_MAX
5922 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5923#endif
5924#ifdef _SC_RTSIG_MAX
5925 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5926#endif
5927#ifdef _SC_SAVED_IDS
5928 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5929#endif
5930#ifdef _SC_SCHAR_MAX
5931 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5932#endif
5933#ifdef _SC_SCHAR_MIN
5934 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5935#endif
5936#ifdef _SC_SELECT
5937 {"SC_SELECT", _SC_SELECT},
5938#endif
5939#ifdef _SC_SEMAPHORES
5940 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5941#endif
5942#ifdef _SC_SEM_NSEMS_MAX
5943 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5944#endif
5945#ifdef _SC_SEM_VALUE_MAX
5946 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5947#endif
5948#ifdef _SC_SHARED_MEMORY_OBJECTS
5949 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5950#endif
5951#ifdef _SC_SHRT_MAX
5952 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5953#endif
5954#ifdef _SC_SHRT_MIN
5955 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5956#endif
5957#ifdef _SC_SIGQUEUE_MAX
5958 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5959#endif
5960#ifdef _SC_SIGRT_MAX
5961 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5962#endif
5963#ifdef _SC_SIGRT_MIN
5964 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5965#endif
Fred Draked86ed291999-12-15 15:34:33 +00005966#ifdef _SC_SOFTPOWER
5967 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5968#endif
Fred Drakec9680921999-12-13 16:37:25 +00005969#ifdef _SC_SPLIT_CACHE
5970 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5971#endif
5972#ifdef _SC_SSIZE_MAX
5973 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5974#endif
5975#ifdef _SC_STACK_PROT
5976 {"SC_STACK_PROT", _SC_STACK_PROT},
5977#endif
5978#ifdef _SC_STREAM_MAX
5979 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5980#endif
5981#ifdef _SC_SYNCHRONIZED_IO
5982 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5983#endif
5984#ifdef _SC_THREADS
5985 {"SC_THREADS", _SC_THREADS},
5986#endif
5987#ifdef _SC_THREAD_ATTR_STACKADDR
5988 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5989#endif
5990#ifdef _SC_THREAD_ATTR_STACKSIZE
5991 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5992#endif
5993#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5994 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5995#endif
5996#ifdef _SC_THREAD_KEYS_MAX
5997 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5998#endif
5999#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6000 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6001#endif
6002#ifdef _SC_THREAD_PRIO_INHERIT
6003 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6004#endif
6005#ifdef _SC_THREAD_PRIO_PROTECT
6006 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6007#endif
6008#ifdef _SC_THREAD_PROCESS_SHARED
6009 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6010#endif
6011#ifdef _SC_THREAD_SAFE_FUNCTIONS
6012 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6013#endif
6014#ifdef _SC_THREAD_STACK_MIN
6015 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6016#endif
6017#ifdef _SC_THREAD_THREADS_MAX
6018 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6019#endif
6020#ifdef _SC_TIMERS
6021 {"SC_TIMERS", _SC_TIMERS},
6022#endif
6023#ifdef _SC_TIMER_MAX
6024 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6025#endif
6026#ifdef _SC_TTY_NAME_MAX
6027 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6028#endif
6029#ifdef _SC_TZNAME_MAX
6030 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6031#endif
6032#ifdef _SC_T_IOV_MAX
6033 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6034#endif
6035#ifdef _SC_UCHAR_MAX
6036 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6037#endif
6038#ifdef _SC_UINT_MAX
6039 {"SC_UINT_MAX", _SC_UINT_MAX},
6040#endif
6041#ifdef _SC_UIO_MAXIOV
6042 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6043#endif
6044#ifdef _SC_ULONG_MAX
6045 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6046#endif
6047#ifdef _SC_USHRT_MAX
6048 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6049#endif
6050#ifdef _SC_VERSION
6051 {"SC_VERSION", _SC_VERSION},
6052#endif
6053#ifdef _SC_WORD_BIT
6054 {"SC_WORD_BIT", _SC_WORD_BIT},
6055#endif
6056#ifdef _SC_XBS5_ILP32_OFF32
6057 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6058#endif
6059#ifdef _SC_XBS5_ILP32_OFFBIG
6060 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6061#endif
6062#ifdef _SC_XBS5_LP64_OFF64
6063 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6064#endif
6065#ifdef _SC_XBS5_LPBIG_OFFBIG
6066 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6067#endif
6068#ifdef _SC_XOPEN_CRYPT
6069 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6070#endif
6071#ifdef _SC_XOPEN_ENH_I18N
6072 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6073#endif
6074#ifdef _SC_XOPEN_LEGACY
6075 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6076#endif
6077#ifdef _SC_XOPEN_REALTIME
6078 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6079#endif
6080#ifdef _SC_XOPEN_REALTIME_THREADS
6081 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6082#endif
6083#ifdef _SC_XOPEN_SHM
6084 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6085#endif
6086#ifdef _SC_XOPEN_UNIX
6087 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6088#endif
6089#ifdef _SC_XOPEN_VERSION
6090 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6091#endif
6092#ifdef _SC_XOPEN_XCU_VERSION
6093 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6094#endif
6095#ifdef _SC_XOPEN_XPG2
6096 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6097#endif
6098#ifdef _SC_XOPEN_XPG3
6099 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6100#endif
6101#ifdef _SC_XOPEN_XPG4
6102 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6103#endif
6104};
6105
6106static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006107conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006108{
6109 return conv_confname(arg, valuep, posix_constants_sysconf,
6110 sizeof(posix_constants_sysconf)
6111 / sizeof(struct constdef));
6112}
6113
6114static char posix_sysconf__doc__[] = "\
6115sysconf(name) -> integer\n\
6116Return an integer-valued system configuration variable.";
6117
6118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006119posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006120{
6121 PyObject *result = NULL;
6122 int name;
6123
6124 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6125 int value;
6126
6127 errno = 0;
6128 value = sysconf(name);
6129 if (value == -1 && errno != 0)
6130 posix_error();
6131 else
6132 result = PyInt_FromLong(value);
6133 }
6134 return result;
6135}
6136#endif
6137
6138
Fred Drakebec628d1999-12-15 18:31:10 +00006139/* This code is used to ensure that the tables of configuration value names
6140 * are in sorted order as required by conv_confname(), and also to build the
6141 * the exported dictionaries that are used to publish information about the
6142 * names available on the host platform.
6143 *
6144 * Sorting the table at runtime ensures that the table is properly ordered
6145 * when used, even for platforms we're not able to test on. It also makes
6146 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006147 */
Fred Drakebec628d1999-12-15 18:31:10 +00006148
6149static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006150cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006151{
6152 const struct constdef *c1 =
6153 (const struct constdef *) v1;
6154 const struct constdef *c2 =
6155 (const struct constdef *) v2;
6156
6157 return strcmp(c1->name, c2->name);
6158}
6159
6160static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006161setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006162 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006163{
Fred Drakebec628d1999-12-15 18:31:10 +00006164 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006165 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006166
6167 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6168 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006169 if (d == NULL)
6170 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006171
Barry Warsaw3155db32000-04-13 15:20:40 +00006172 for (i=0; i < tablesize; ++i) {
6173 PyObject *o = PyInt_FromLong(table[i].value);
6174 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6175 Py_XDECREF(o);
6176 Py_DECREF(d);
6177 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006178 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006179 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006180 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006181 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006182}
6183
Fred Drakebec628d1999-12-15 18:31:10 +00006184/* Return -1 on failure, 0 on success. */
6185static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006186setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006187{
6188#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006189 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006190 sizeof(posix_constants_pathconf)
6191 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006192 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006193 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006194#endif
6195#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006196 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006197 sizeof(posix_constants_confstr)
6198 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006199 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006200 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006201#endif
6202#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006203 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006204 sizeof(posix_constants_sysconf)
6205 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006206 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006207 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006208#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006209 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006210}
Fred Draked86ed291999-12-15 15:34:33 +00006211
6212
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006213static char posix_abort__doc__[] = "\
6214abort() -> does not return!\n\
6215Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
6216in the hardest way possible on the hosting operating system.";
6217
6218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006219posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006220{
6221 if (!PyArg_ParseTuple(args, ":abort"))
6222 return NULL;
6223 abort();
6224 /*NOTREACHED*/
6225 Py_FatalError("abort() called from Python code didn't abort!");
6226 return NULL;
6227}
Fred Drakebec628d1999-12-15 18:31:10 +00006228
Tim Petersf58a7aa2000-09-22 10:05:54 +00006229#ifdef MS_WIN32
6230static char win32_startfile__doc__[] = "\
6231startfile(filepath) - Start a file with its associated application.\n\
6232\n\
6233This acts like double-clicking the file in Explorer, or giving the file\n\
6234name as an argument to the DOS \"start\" command: the file is opened\n\
6235with whatever application (if any) its extension is associated.\n\
6236\n\
6237startfile returns as soon as the associated application is launched.\n\
6238There is no option to wait for the application to close, and no way\n\
6239to retrieve the application's exit status.\n\
6240\n\
6241The filepath is relative to the current directory. If you want to use\n\
6242an absolute path, make sure the first character is not a slash (\"/\");\n\
6243the underlying Win32 ShellExecute function doesn't work if it is.";
6244
6245static PyObject *
6246win32_startfile(PyObject *self, PyObject *args)
6247{
6248 char *filepath;
6249 HINSTANCE rc;
6250 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6251 return NULL;
6252 Py_BEGIN_ALLOW_THREADS
6253 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6254 Py_END_ALLOW_THREADS
6255 if (rc <= (HINSTANCE)32)
6256 return win32_error("startfile", filepath);
6257 Py_INCREF(Py_None);
6258 return Py_None;
6259}
6260#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006261
6262static PyMethodDef posix_methods[] = {
6263 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6264#ifdef HAVE_TTYNAME
6265 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6266#endif
6267 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6268 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006269#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006270 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006271#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006272#ifdef HAVE_CHROOT
6273 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6274#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006275#ifdef HAVE_CTERMID
6276 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6277#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006278#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006279 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006280#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006281#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006282 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006283#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006284 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6285 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6286 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006287#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006288 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006289#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006290#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006291 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006292#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006293 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6294 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6295 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006296#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006297 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006298#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006299#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006300 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006301#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006302 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006303#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006304 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006305#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006306 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6307 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6308 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006309#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006310 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006311#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006312 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006313#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006314 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6315 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006316#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006317#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006318 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6319 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006320#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006321#ifdef HAVE_FORK1
6322 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6323#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006324#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006325 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006326#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006327#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006328 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006329#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006330#ifdef HAVE_FORKPTY
6331 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6332#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006333#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006334 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006335#endif /* HAVE_GETEGID */
6336#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006337 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006338#endif /* HAVE_GETEUID */
6339#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006340 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006341#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006342#ifdef HAVE_GETGROUPS
6343 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6344#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006345 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006346#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006347 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006348#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006349#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006350 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006351#endif /* HAVE_GETPPID */
6352#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006353 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006354#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006355#ifdef HAVE_GETLOGIN
6356 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6357#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006358#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006359 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006360#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006361#ifdef HAVE_KILLPG
6362 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6363#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006364#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006366#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006367#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006368 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006369#ifdef MS_WIN32
6370 {"popen2", win32_popen2, METH_VARARGS},
6371 {"popen3", win32_popen3, METH_VARARGS},
6372 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006373 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006374#else
6375#if defined(PYOS_OS2) && defined(PYCC_GCC)
6376 {"popen2", os2emx_popen2, METH_VARARGS},
6377 {"popen3", os2emx_popen3, METH_VARARGS},
6378 {"popen4", os2emx_popen4, METH_VARARGS},
6379#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006380#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006381#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006382#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006383 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006384#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006385#ifdef HAVE_SETEUID
6386 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6387#endif /* HAVE_SETEUID */
6388#ifdef HAVE_SETEGID
6389 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6390#endif /* HAVE_SETEGID */
6391#ifdef HAVE_SETREUID
6392 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6393#endif /* HAVE_SETREUID */
6394#ifdef HAVE_SETREGID
6395 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6396#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006397#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006398 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006399#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006400#ifdef HAVE_SETGROUPS
6401 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6402#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006403#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006404 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006405#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006406#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006407 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006408#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006409#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006410 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006411#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006412#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006413 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006414#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006415#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006416 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006417#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006418#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006419 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006420#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006421#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006422 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006423#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006424 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6425 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6426 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6427 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6428 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6429 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6430 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6431 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6432 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006433 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006434#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006435 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006436#endif
6437#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006438 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006439#endif
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006440#ifdef HAVE_MKNOD
6441 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6442#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006443#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006444 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006445#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006446#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006447 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006448#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006449#ifdef HAVE_UNSETENV
6450 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6451#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006452#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006453 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006454#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006455#ifdef HAVE_FCHDIR
6456 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6457#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006458#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006459 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006460#endif
6461#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006462 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006463#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006464#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006465#ifdef WCOREDUMP
6466 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6467#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006468#ifdef WIFCONTINUED
6469 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6470#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006471#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006472 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006473#endif /* WIFSTOPPED */
6474#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006475 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006476#endif /* WIFSIGNALED */
6477#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006478 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006479#endif /* WIFEXITED */
6480#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006481 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006482#endif /* WEXITSTATUS */
6483#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006484 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006485#endif /* WTERMSIG */
6486#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006487 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006488#endif /* WSTOPSIG */
6489#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006490#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006491 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006492#endif
6493#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006494 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006495#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006496#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006497 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6498#endif
6499#ifdef HAVE_TEMPNAM
6500 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6501#endif
6502#ifdef HAVE_TMPNAM
6503 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6504#endif
Fred Drakec9680921999-12-13 16:37:25 +00006505#ifdef HAVE_CONFSTR
6506 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6507#endif
6508#ifdef HAVE_SYSCONF
6509 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6510#endif
6511#ifdef HAVE_FPATHCONF
6512 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6513#endif
6514#ifdef HAVE_PATHCONF
6515 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6516#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006517 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00006518#ifdef MS_WIN32
6519 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6520#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006521 {NULL, NULL} /* Sentinel */
6522};
6523
6524
Barry Warsaw4a342091996-12-19 23:50:02 +00006525static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006526ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006527{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006528 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006529}
6530
Guido van Rossumd48f2521997-12-05 22:19:34 +00006531#if defined(PYOS_OS2)
6532/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006533static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006534{
6535 APIRET rc;
6536 ULONG values[QSV_MAX+1];
6537 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006538 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006539
6540 Py_BEGIN_ALLOW_THREADS
6541 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6542 Py_END_ALLOW_THREADS
6543
6544 if (rc != NO_ERROR) {
6545 os2_error(rc);
6546 return -1;
6547 }
6548
Fred Drake4d1e64b2002-04-15 19:40:07 +00006549 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6550 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6551 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6552 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6553 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6554 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6555 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006556
6557 switch (values[QSV_VERSION_MINOR]) {
6558 case 0: ver = "2.00"; break;
6559 case 10: ver = "2.10"; break;
6560 case 11: ver = "2.11"; break;
6561 case 30: ver = "3.00"; break;
6562 case 40: ver = "4.00"; break;
6563 case 50: ver = "5.00"; break;
6564 default:
Tim Peters885d4572001-11-28 20:27:42 +00006565 PyOS_snprintf(tmp, sizeof(tmp),
6566 "%d-%d", values[QSV_VERSION_MAJOR],
6567 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006568 ver = &tmp[0];
6569 }
6570
6571 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006572 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006573 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006574
6575 /* Add Indicator of Which Drive was Used to Boot the System */
6576 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6577 tmp[1] = ':';
6578 tmp[2] = '\0';
6579
Fred Drake4d1e64b2002-04-15 19:40:07 +00006580 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006581}
6582#endif
6583
Barry Warsaw4a342091996-12-19 23:50:02 +00006584static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006585all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006586{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006587#ifdef F_OK
6588 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006589#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006590#ifdef R_OK
6591 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006592#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006593#ifdef W_OK
6594 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006595#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006596#ifdef X_OK
6597 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006598#endif
Fred Drakec9680921999-12-13 16:37:25 +00006599#ifdef NGROUPS_MAX
6600 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6601#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006602#ifdef TMP_MAX
6603 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6604#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006605#ifdef WCONTINUED
6606 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6607#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006608#ifdef WNOHANG
6609 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006610#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006611#ifdef WUNTRACED
6612 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6613#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006614#ifdef O_RDONLY
6615 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6616#endif
6617#ifdef O_WRONLY
6618 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6619#endif
6620#ifdef O_RDWR
6621 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6622#endif
6623#ifdef O_NDELAY
6624 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6625#endif
6626#ifdef O_NONBLOCK
6627 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6628#endif
6629#ifdef O_APPEND
6630 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6631#endif
6632#ifdef O_DSYNC
6633 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6634#endif
6635#ifdef O_RSYNC
6636 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6637#endif
6638#ifdef O_SYNC
6639 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6640#endif
6641#ifdef O_NOCTTY
6642 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6643#endif
6644#ifdef O_CREAT
6645 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6646#endif
6647#ifdef O_EXCL
6648 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6649#endif
6650#ifdef O_TRUNC
6651 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6652#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006653#ifdef O_BINARY
6654 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6655#endif
6656#ifdef O_TEXT
6657 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6658#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006659#ifdef O_LARGEFILE
6660 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6661#endif
6662
Tim Peters5aa91602002-01-30 05:46:57 +00006663/* MS Windows */
6664#ifdef O_NOINHERIT
6665 /* Don't inherit in child processes. */
6666 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6667#endif
6668#ifdef _O_SHORT_LIVED
6669 /* Optimize for short life (keep in memory). */
6670 /* MS forgot to define this one with a non-underscore form too. */
6671 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6672#endif
6673#ifdef O_TEMPORARY
6674 /* Automatically delete when last handle is closed. */
6675 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6676#endif
6677#ifdef O_RANDOM
6678 /* Optimize for random access. */
6679 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6680#endif
6681#ifdef O_SEQUENTIAL
6682 /* Optimize for sequential access. */
6683 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6684#endif
6685
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006686/* GNU extensions. */
6687#ifdef O_DIRECT
6688 /* Direct disk access. */
6689 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6690#endif
6691#ifdef O_DIRECTORY
6692 /* Must be a directory. */
6693 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6694#endif
6695#ifdef O_NOFOLLOW
6696 /* Do not follow links. */
6697 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6698#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006699
Guido van Rossum246bc171999-02-01 23:54:31 +00006700#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006701#if defined(PYOS_OS2) && defined(PYCC_GCC)
6702 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6703 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6704 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6705 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6706 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6707 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6708 if (ins(d, "P_PM", (long)P_PM)) return -1;
6709 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6710 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6711 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6712 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6713 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6714 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6715 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6716 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6717 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6718 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6719 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6720 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6721 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6722#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006723 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6724 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6725 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6726 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6727 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006728#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006729#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006730
Guido van Rossumd48f2521997-12-05 22:19:34 +00006731#if defined(PYOS_OS2)
6732 if (insertvalues(d)) return -1;
6733#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006734 return 0;
6735}
6736
6737
Tim Peters5aa91602002-01-30 05:46:57 +00006738#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006739#define INITFUNC initnt
6740#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006741
6742#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006743#define INITFUNC initos2
6744#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006745
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006746#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006747#define INITFUNC initposix
6748#define MODNAME "posix"
6749#endif
6750
Guido van Rossum3886bb61998-12-04 18:50:17 +00006751DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006752INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006753{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006754 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006755
Fred Drake4d1e64b2002-04-15 19:40:07 +00006756 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006757 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006758 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006759
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006760 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006761 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006762 Py_XINCREF(v);
6763 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006764 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006765 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006766
Fred Drake4d1e64b2002-04-15 19:40:07 +00006767 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006768 return;
6769
Fred Drake4d1e64b2002-04-15 19:40:07 +00006770 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006771 return;
6772
Fred Drake4d1e64b2002-04-15 19:40:07 +00006773 Py_INCREF(PyExc_OSError);
6774 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006775
Guido van Rossumb3d39562000-01-31 18:41:26 +00006776#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006777 if (posix_putenv_garbage == NULL)
6778 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006779#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006780
Guido van Rossum14648392001-12-08 18:02:58 +00006781 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006782 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006783 Py_INCREF((PyObject*) &StatResultType);
6784 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006785
Guido van Rossum14648392001-12-08 18:02:58 +00006786 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006787 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006788 Py_INCREF((PyObject*) &StatVFSResultType);
6789 PyModule_AddObject(m, "statvfs_result",
6790 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006791}