blob: 4d9408a024ecb0ee68f3d5864ba3a8ee70276fdf [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +00007 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000016static char posix__doc__ [] =
17"This module provides access to operating system functionality that is\n\
18standardized by the C Standard and the POSIX standard (a thinly\n\
19disguised Unix interface). Refer to the library manual and\n\
20corresponding Unix manual entries for more information on calls.";
21
Barry Warsaw53699e91996-12-10 23:23:01 +000022#include "Python.h"
Guido van Rossum98bf58f2001-10-18 20:34:25 +000023#include "structseq.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000024
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000025#if defined(PYOS_OS2)
26#define INCL_DOS
27#define INCL_DOSERRORS
28#define INCL_DOSPROCESS
29#define INCL_NOPMAPI
30#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000031#if defined(PYCC_GCC)
32#include <ctype.h>
33#include <io.h>
34#include <stdio.h>
35#include <process.h>
36#include "osdefs.h"
37#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000038#endif
39
Guido van Rossumb6775db1994-08-01 11:34:53 +000040#include <sys/types.h>
41#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000042
Guido van Rossum36bc6801995-06-14 22:54:23 +000043#ifdef HAVE_SYS_WAIT_H
44#include <sys/wait.h> /* For WNOHANG */
45#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000046
Guido van Rossuma376cc51996-12-05 23:43:35 +000047#ifdef HAVE_SIGNAL_H
48#include <signal.h>
49#endif
50
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#ifdef HAVE_FCNTL_H
52#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000053#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000054
Guido van Rossuma6535fd2001-10-18 19:44:10 +000055#ifdef HAVE_GRP_H
56#include <grp.h>
57#endif
58
Guido van Rossuma4916fa1996-05-23 22:58:55 +000059/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000060/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000062#include <process.h>
63#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000064#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000065#define HAVE_GETCWD 1
66#define HAVE_OPENDIR 1
67#define HAVE_SYSTEM 1
68#if defined(__OS2__)
69#define HAVE_EXECV 1
70#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000071#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072#include <process.h>
73#else
74#ifdef __BORLANDC__ /* Borland compiler */
75#define HAVE_EXECV 1
76#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#define HAVE_OPENDIR 1
78#define HAVE_PIPE 1
79#define HAVE_POPEN 1
80#define HAVE_SYSTEM 1
81#define HAVE_WAIT 1
82#else
83#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000084#define HAVE_GETCWD 1
85#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000086#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000087#define HAVE_EXECV 1
88#define HAVE_PIPE 1
89#define HAVE_POPEN 1
90#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000091#define HAVE_CWAIT 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000093#endif /* !MS_WIN32 */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000094#else
95#if defined(PYOS_OS2) && defined(PYCC_GCC)
96/* Everything needed is defined in PC/os2emx/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000097#else /* all other compilers */
98/* Unix functions that the configure script doesn't check for */
99#define HAVE_EXECV 1
100#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000101#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
102#define HAVE_FORK1 1
103#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000104#define HAVE_GETCWD 1
105#define HAVE_GETEGID 1
106#define HAVE_GETEUID 1
107#define HAVE_GETGID 1
108#define HAVE_GETPPID 1
109#define HAVE_GETUID 1
110#define HAVE_KILL 1
111#define HAVE_OPENDIR 1
112#define HAVE_PIPE 1
113#define HAVE_POPEN 1
114#define HAVE_SYSTEM 1
115#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000116#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000117#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#endif /* _MSC_VER */
119#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000120#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000121#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000122
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000123#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000124
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000125#if defined(sun) && !defined(__SVR4)
126/* SunOS 4.1.4 doesn't have prototypes for these: */
127extern int rename(const char *, const char *);
128extern int pclose(FILE *);
129extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000130extern int fsync(int);
131extern int lstat(const char *, struct stat *);
132extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000133#endif
134
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000135#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000136#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000138#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000139#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000142extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000144#endif
145#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(char *);
147extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(const char *);
150extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000152#ifdef __BORLANDC__
153extern int chmod(const char *, int);
154#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000156#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int chown(const char *, uid_t, gid_t);
158extern char *getcwd(char *, int);
159extern char *strerror(int);
160extern int link(const char *, const char *);
161extern int rename(const char *, const char *);
162extern int stat(const char *, struct stat *);
163extern int unlink(const char *);
164extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000167#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000170#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000172
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175#ifdef HAVE_UTIME_H
176#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000177#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000179#ifdef HAVE_SYS_UTIME_H
180#include <sys/utime.h>
181#define HAVE_UTIME_H /* pretend we do for the rest of this file */
182#endif /* HAVE_SYS_UTIME_H */
183
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184#ifdef HAVE_SYS_TIMES_H
185#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000186#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187
188#ifdef HAVE_SYS_PARAM_H
189#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000190#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000191
192#ifdef HAVE_SYS_UTSNAME_H
193#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000194#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000196#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000198#define NAMLEN(dirent) strlen((dirent)->d_name)
199#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000200#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#include <direct.h>
202#define NAMLEN(dirent) strlen((dirent)->d_name)
203#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000206#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000207#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#include <direct.h>
220#include <io.h>
221#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000222#include "osdefs.h"
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000223#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000225#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000227#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#else /* 16-bit Windows */
229#include <dos.h>
230#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000231#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233
Guido van Rossumd48f2521997-12-05 22:19:34 +0000234#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000236#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
Tim Petersbc2e10e2002-03-03 23:17:02 +0000238#ifndef MAXPATHLEN
239#define MAXPATHLEN 1024
240#endif /* MAXPATHLEN */
241
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000242#ifdef UNION_WAIT
243/* Emulate some macros on systems that have a union instead of macros */
244
245#ifndef WIFEXITED
246#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
247#endif
248
249#ifndef WEXITSTATUS
250#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
251#endif
252
253#ifndef WTERMSIG
254#define WTERMSIG(u_wait) ((u_wait).w_termsig)
255#endif
256
257#endif /* UNION_WAIT */
258
Greg Wardb48bc172000-03-01 21:51:56 +0000259/* Don't use the "_r" form if we don't need it (also, won't have a
260 prototype for it, at least on Solaris -- maybe others as well?). */
261#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
262#define USE_CTERMID_R
263#endif
264
265#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
266#define USE_TMPNAM_R
267#endif
268
Fred Drake699f3522000-06-29 21:12:41 +0000269/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000270#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000271#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000272# define STAT _stati64
273# define FSTAT _fstati64
274# define STRUCT_STAT struct _stati64
275#else
276# define STAT stat
277# define FSTAT fstat
278# define STRUCT_STAT struct stat
279#endif
280
281
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282/* Return a dictionary corresponding to the POSIX environment table */
283
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000284#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000286#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287
Barry Warsaw53699e91996-12-10 23:23:01 +0000288static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000289convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290{
Barry Warsaw53699e91996-12-10 23:23:01 +0000291 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000293 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 if (d == NULL)
295 return NULL;
296 if (environ == NULL)
297 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000298 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000300 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000301 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 char *p = strchr(*e, '=');
303 if (p == NULL)
304 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000305 k = PyString_FromStringAndSize(*e, (int)(p-*e));
306 if (k == NULL) {
307 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000309 }
310 v = PyString_FromString(p+1);
311 if (v == NULL) {
312 PyErr_Clear();
313 Py_DECREF(k);
314 continue;
315 }
316 if (PyDict_GetItem(d, k) == NULL) {
317 if (PyDict_SetItem(d, k, v) != 0)
318 PyErr_Clear();
319 }
320 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000321 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000323#if defined(PYOS_OS2)
324 {
325 APIRET rc;
326 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
327
328 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000329 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000330 PyObject *v = PyString_FromString(buffer);
331 PyDict_SetItemString(d, "BEGINLIBPATH", v);
332 Py_DECREF(v);
333 }
334 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
335 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
336 PyObject *v = PyString_FromString(buffer);
337 PyDict_SetItemString(d, "ENDLIBPATH", v);
338 Py_DECREF(v);
339 }
340 }
341#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342 return d;
343}
344
345
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346/* Set a POSIX-specific error from errno, and return NULL */
347
Barry Warsawd58d7641998-07-23 16:14:40 +0000348static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000349posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000350{
Barry Warsawca74da41999-02-09 19:31:45 +0000351 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000352}
Barry Warsawd58d7641998-07-23 16:14:40 +0000353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000354posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000355{
Barry Warsawca74da41999-02-09 19:31:45 +0000356 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000357}
358
Mark Hammondef8b6542001-05-13 08:04:26 +0000359static PyObject *
360posix_error_with_allocated_filename(char* name)
361{
362 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
363 PyMem_Free(name);
364 return rc;
365}
366
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000367#ifdef MS_WIN32
368static PyObject *
369win32_error(char* function, char* filename)
370{
Mark Hammond33a6da92000-08-15 00:46:38 +0000371 /* XXX We should pass the function name along in the future.
372 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000373 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000374 Windows error object, which is non-trivial.
375 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000376 errno = GetLastError();
377 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000378 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000379 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000380 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000381}
382#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000383
Guido van Rossumd48f2521997-12-05 22:19:34 +0000384#if defined(PYOS_OS2)
385/**********************************************************************
386 * Helper Function to Trim and Format OS/2 Messages
387 **********************************************************************/
388 static void
389os2_formatmsg(char *msgbuf, int msglen, char *reason)
390{
391 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
392
393 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
394 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
395
396 while (lastc > msgbuf && isspace(*lastc))
397 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
398 }
399
400 /* Add Optional Reason Text */
401 if (reason) {
402 strcat(msgbuf, " : ");
403 strcat(msgbuf, reason);
404 }
405}
406
407/**********************************************************************
408 * Decode an OS/2 Operating System Error Code
409 *
410 * A convenience function to lookup an OS/2 error code and return a
411 * text message we can use to raise a Python exception.
412 *
413 * Notes:
414 * The messages for errors returned from the OS/2 kernel reside in
415 * the file OSO001.MSG in the \OS2 directory hierarchy.
416 *
417 **********************************************************************/
418 static char *
419os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
420{
421 APIRET rc;
422 ULONG msglen;
423
424 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
425 Py_BEGIN_ALLOW_THREADS
426 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
427 errorcode, "oso001.msg", &msglen);
428 Py_END_ALLOW_THREADS
429
430 if (rc == NO_ERROR)
431 os2_formatmsg(msgbuf, msglen, reason);
432 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000433 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000434 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000435
436 return msgbuf;
437}
438
439/* Set an OS/2-specific error and return NULL. OS/2 kernel
440 errors are not in a global variable e.g. 'errno' nor are
441 they congruent with posix error numbers. */
442
443static PyObject * os2_error(int code)
444{
445 char text[1024];
446 PyObject *v;
447
448 os2_strerror(text, sizeof(text), code, "");
449
450 v = Py_BuildValue("(is)", code, text);
451 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000452 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000453 Py_DECREF(v);
454 }
455 return NULL; /* Signal to Python that an Exception is Pending */
456}
457
458#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459
460/* POSIX generic methods */
461
Barry Warsaw53699e91996-12-10 23:23:01 +0000462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000463posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000464{
465 int fd;
466 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000467 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000468 return NULL;
469 Py_BEGIN_ALLOW_THREADS
470 res = (*func)(fd);
471 Py_END_ALLOW_THREADS
472 if (res < 0)
473 return posix_error();
474 Py_INCREF(Py_None);
475 return Py_None;
476}
477
478
479static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000480posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481{
Mark Hammondef8b6542001-05-13 08:04:26 +0000482 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000483 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000484 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000485 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000487 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000488 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000489 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000491 return posix_error_with_allocated_filename(path1);
492 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000493 Py_INCREF(Py_None);
494 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000495}
496
Barry Warsaw53699e91996-12-10 23:23:01 +0000497static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000498posix_2str(PyObject *args, char *format,
499 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500{
Mark Hammondef8b6542001-05-13 08:04:26 +0000501 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000502 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000503 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000504 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000505 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000506 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000507 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000508 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000509 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000510 PyMem_Free(path1);
511 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000512 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000513 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000515 Py_INCREF(Py_None);
516 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517}
518
Tim Peters5aa91602002-01-30 05:46:57 +0000519static char stat_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000520"stat_result: Result from stat or lstat.\n\n\
521This object may be accessed either as a tuple of\n\
522 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
523or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
524\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000525Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000526they are available as attributes only.\n\
527\n\
528See os.stat for more information.\n";
529
530static PyStructSequence_Field stat_result_fields[] = {
531 {"st_mode", "protection bits"},
532 {"st_ino", "inode"},
533 {"st_dev", "device"},
534 {"st_nlink", "number of hard links"},
535 {"st_uid", "user ID of owner"},
536 {"st_gid", "group ID of owner"},
537 {"st_size", "total size, in bytes"},
538 {"st_atime", "time of last access"},
539 {"st_mtime", "time of last modification"},
540 {"st_ctime", "time of last change"},
541#ifdef HAVE_ST_BLKSIZE
542 {"st_blksize", "blocksize for filesystem I/O"},
543#endif
544#ifdef HAVE_ST_BLOCKS
545 {"st_blocks", "number of blocks allocated"},
546#endif
547#ifdef HAVE_ST_RDEV
548 {"st_rdev", "device type (if inode device)"},
549#endif
550 {0}
551};
552
553#ifdef HAVE_ST_BLKSIZE
554#define ST_BLKSIZE_IDX 10
555#else
556#define ST_BLKSIZE_IDX 9
557#endif
558
559#ifdef HAVE_ST_BLOCKS
560#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
561#else
562#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
563#endif
564
565#ifdef HAVE_ST_RDEV
566#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
567#else
568#define ST_RDEV_IDX ST_BLOCKS_IDX
569#endif
570
571static PyStructSequence_Desc stat_result_desc = {
572 "stat_result", /* name */
573 stat_result__doc__, /* doc */
574 stat_result_fields,
575 10
576};
577
Tim Peters5aa91602002-01-30 05:46:57 +0000578static char statvfs_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000579"statvfs_result: Result from statvfs or fstatvfs.\n\n\
580This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000581 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
582or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000583\n\
584See os.statvfs for more information.\n";
585
586static PyStructSequence_Field statvfs_result_fields[] = {
587 {"f_bsize", },
588 {"f_frsize", },
589 {"f_blocks", },
590 {"f_bfree", },
591 {"f_bavail", },
592 {"f_files", },
593 {"f_ffree", },
594 {"f_favail", },
595 {"f_flag", },
596 {"f_namemax",},
597 {0}
598};
599
600static PyStructSequence_Desc statvfs_result_desc = {
601 "statvfs_result", /* name */
602 statvfs_result__doc__, /* doc */
603 statvfs_result_fields,
604 10
605};
606
607static PyTypeObject StatResultType;
608static PyTypeObject StatVFSResultType;
609
Tim Peters5aa91602002-01-30 05:46:57 +0000610/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000611 (used by posix_stat() and posix_fstat()) */
612static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000613_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000614{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000615 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000616 if (v == NULL)
617 return NULL;
618
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000619 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000620#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000621 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000622 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000623#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000624 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000625#endif
626#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000627 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000628 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000629#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000630 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000631#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000632 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
633 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
634 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000635#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000636 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000637 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000638#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000639 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000640#endif
641#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000642 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000643 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000644 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000645 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000646 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000647 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000648#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000649 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
650 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
651 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
652#endif
653
654#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000655 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000656 PyInt_FromLong((long)st.st_blksize));
657#endif
658#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000659 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000660 PyInt_FromLong((long)st.st_blocks));
661#endif
662#ifdef HAVE_ST_RDEV
663 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
664 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000665#endif
666
667 if (PyErr_Occurred()) {
668 Py_DECREF(v);
669 return NULL;
670 }
671
672 return v;
673}
674
Barry Warsaw53699e91996-12-10 23:23:01 +0000675static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000676posix_do_stat(PyObject *self, PyObject *args, char *format,
677 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000678{
Fred Drake699f3522000-06-29 21:12:41 +0000679 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000680 char *path = NULL; /* pass this to stat; do not free() it */
681 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000682 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000683
684#ifdef MS_WIN32
Tim Peters500bd032001-12-19 19:05:01 +0000685 int pathlen;
686 char pathcopy[MAX_PATH];
Guido van Rossumace88ae2000-04-21 18:54:45 +0000687#endif /* MS_WIN32 */
688
Tim Peters5aa91602002-01-30 05:46:57 +0000689 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000690 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000692 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000693
694#ifdef MS_WIN32
695 pathlen = strlen(path);
696 /* the library call can blow up if the file name is too long! */
697 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000698 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000699 errno = ENAMETOOLONG;
700 return posix_error();
701 }
702
Tim Peters500bd032001-12-19 19:05:01 +0000703 /* Remove trailing slash or backslash, unless it's the current
704 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
705 */
706 if (pathlen > 0 &&
707 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
708 /* It does end with a slash -- exempt the root drive cases. */
709 /* XXX UNC root drives should also be exempted? */
710 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
711 /* leave it alone */;
712 else {
713 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000714 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000715 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000716 path = pathcopy;
717 }
718 }
719#endif /* MS_WIN32 */
720
Barry Warsaw53699e91996-12-10 23:23:01 +0000721 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000722 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000723 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000724 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000725 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000726
Tim Peters500bd032001-12-19 19:05:01 +0000727 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000728 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000729}
730
731
732/* POSIX methods */
733
Guido van Rossum94f6f721999-01-06 18:42:14 +0000734static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000735"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000736Test for access to a file.";
737
738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000739posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000740{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000741 char *path;
742 int mode;
743 int res;
744
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000745 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000746 return NULL;
747 Py_BEGIN_ALLOW_THREADS
748 res = access(path, mode);
749 Py_END_ALLOW_THREADS
750 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000751}
752
Guido van Rossumd371ff11999-01-25 16:12:23 +0000753#ifndef F_OK
754#define F_OK 0
755#endif
756#ifndef R_OK
757#define R_OK 4
758#endif
759#ifndef W_OK
760#define W_OK 2
761#endif
762#ifndef X_OK
763#define X_OK 1
764#endif
765
766#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000767static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000768"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000769Return the name of the terminal device connected to 'fd'.";
770
771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000772posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000773{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000774 int id;
775 char *ret;
776
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000777 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000778 return NULL;
779
Guido van Rossum94f6f721999-01-06 18:42:14 +0000780 ret = ttyname(id);
781 if (ret == NULL)
782 return(posix_error());
783 return(PyString_FromString(ret));
784}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000785#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000786
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000787#ifdef HAVE_CTERMID
788static char posix_ctermid__doc__[] =
789"ctermid() -> String\n\
790Return the name of the controlling terminal for this process.";
791
792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000793posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000794{
795 char *ret;
796 char buffer[L_ctermid];
797
798 if (!PyArg_ParseTuple(args, ":ctermid"))
799 return NULL;
800
Greg Wardb48bc172000-03-01 21:51:56 +0000801#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000802 ret = ctermid_r(buffer);
803#else
804 ret = ctermid(buffer);
805#endif
806 if (ret == NULL)
807 return(posix_error());
808 return(PyString_FromString(buffer));
809}
810#endif
811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000812static char posix_chdir__doc__[] =
813"chdir(path) -> None\n\
814Change the current working directory to the specified path.";
815
Barry Warsaw53699e91996-12-10 23:23:01 +0000816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000817posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000819#if defined(PYOS_OS2) && defined(PYCC_GCC)
820 return posix_1str(args, "et:chdir", _chdir2);
821#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000822 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000823#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824}
825
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000826
827static char posix_chmod__doc__[] =
828"chmod(path, mode) -> None\n\
829Change the access permissions of a file.";
830
Barry Warsaw53699e91996-12-10 23:23:01 +0000831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000832posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000833{
Mark Hammondef8b6542001-05-13 08:04:26 +0000834 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000835 int i;
836 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000837 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000838 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000839 return NULL;
840 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000841 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000842 Py_END_ALLOW_THREADS
843 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000844 return posix_error_with_allocated_filename(path);
845 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000846 Py_INCREF(Py_None);
847 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000848}
849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000850
Martin v. Löwis244edc82001-10-04 22:44:26 +0000851#ifdef HAVE_CHROOT
Tim Peters5aa91602002-01-30 05:46:57 +0000852static char posix_chroot__doc__[] =
Martin v. Löwis244edc82001-10-04 22:44:26 +0000853"chroot(path) -> None\n\
854Change root directory to path.";
855
856static PyObject *
857posix_chroot(PyObject *self, PyObject *args)
858{
859 return posix_1str(args, "et:chroot", chroot);
860}
861#endif
862
Guido van Rossum21142a01999-01-08 21:05:37 +0000863#ifdef HAVE_FSYNC
864static char posix_fsync__doc__[] =
865"fsync(fildes) -> None\n\
866force write of file with filedescriptor to disk.";
867
868static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000869posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000870{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000871 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000872}
873#endif /* HAVE_FSYNC */
874
875#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000876
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000877#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000878extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
879#endif
880
Guido van Rossum21142a01999-01-08 21:05:37 +0000881static char posix_fdatasync__doc__[] =
882"fdatasync(fildes) -> None\n\
883force write of file with filedescriptor to disk.\n\
884 does not force update of metadata.";
885
886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000887posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000888{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000889 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000890}
891#endif /* HAVE_FDATASYNC */
892
893
Fredrik Lundh10723342000-07-10 16:38:09 +0000894#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000895static char posix_chown__doc__[] =
896"chown(path, uid, gid) -> None\n\
897Change the owner and group id of path to the numeric uid and gid.";
898
Barry Warsaw53699e91996-12-10 23:23:01 +0000899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000900posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000901{
Mark Hammondef8b6542001-05-13 08:04:26 +0000902 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000903 int uid, gid;
904 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000905 if (!PyArg_ParseTuple(args, "etii:chown",
906 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000907 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000908 return NULL;
909 Py_BEGIN_ALLOW_THREADS
910 res = chown(path, (uid_t) uid, (gid_t) gid);
911 Py_END_ALLOW_THREADS
912 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000913 return posix_error_with_allocated_filename(path);
914 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000915 Py_INCREF(Py_None);
916 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000917}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000918#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000919
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000920
Guido van Rossum36bc6801995-06-14 22:54:23 +0000921#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000922static char posix_getcwd__doc__[] =
923"getcwd() -> path\n\
924Return a string representing the current working directory.";
925
Barry Warsaw53699e91996-12-10 23:23:01 +0000926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000927posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000928{
929 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000930 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000931 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000932 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000933 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000934#if defined(PYOS_OS2) && defined(PYCC_GCC)
935 res = _getcwd2(buf, sizeof buf);
936#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000937 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000938#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000939 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000940 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000941 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000942 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000943}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000944#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000946
Guido van Rossumb6775db1994-08-01 11:34:53 +0000947#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000948static char posix_link__doc__[] =
949"link(src, dst) -> None\n\
950Create a hard link to a file.";
951
Barry Warsaw53699e91996-12-10 23:23:01 +0000952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000953posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954{
Mark Hammondef8b6542001-05-13 08:04:26 +0000955 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000957#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000959
960static char posix_listdir__doc__[] =
961"listdir(path) -> list_of_strings\n\
962Return a list containing the names of the entries in the directory.\n\
963\n\
964 path: path of directory to list\n\
965\n\
966The list is in arbitrary order. It does not include the special\n\
967entries '.' and '..' even if they are present in the directory.";
968
Barry Warsaw53699e91996-12-10 23:23:01 +0000969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000970posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000971{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000972 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000973 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000974#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000975
Barry Warsaw53699e91996-12-10 23:23:01 +0000976 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000977 HANDLE hFindFile;
978 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000979 /* MAX_PATH characters could mean a bigger encoded string */
980 char namebuf[MAX_PATH*2+5];
981 char *bufptr = namebuf;
982 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000983 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000984
Tim Peters5aa91602002-01-30 05:46:57 +0000985 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +0000986 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000987 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000988 ch = namebuf[len-1];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000989 if (ch != SEP && ch != ALTSEP && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000990 namebuf[len++] = '/';
991 strcpy(namebuf + len, "*.*");
992
Barry Warsaw53699e91996-12-10 23:23:01 +0000993 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000994 return NULL;
995
996 hFindFile = FindFirstFile(namebuf, &FileData);
997 if (hFindFile == INVALID_HANDLE_VALUE) {
998 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000999 if (errno == ERROR_FILE_NOT_FOUND)
1000 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001001 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001002 }
1003 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001004 if (FileData.cFileName[0] == '.' &&
1005 (FileData.cFileName[1] == '\0' ||
1006 FileData.cFileName[1] == '.' &&
1007 FileData.cFileName[2] == '\0'))
1008 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001009 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001010 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001011 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001012 d = NULL;
1013 break;
1014 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001015 if (PyList_Append(d, v) != 0) {
1016 Py_DECREF(v);
1017 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001018 d = NULL;
1019 break;
1020 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001021 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001022 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1023
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001024 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001025 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001026
1027 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001028
Tim Peters0bb44a42000-09-15 07:44:49 +00001029#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001030
1031#ifndef MAX_PATH
1032#define MAX_PATH 250
1033#endif
1034 char *name, *pt;
1035 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001036 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001037 char namebuf[MAX_PATH+5];
1038 struct _find_t ep;
1039
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001040 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001041 return NULL;
1042 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001043 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001044 return NULL;
1045 }
1046 strcpy(namebuf, name);
1047 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001048 if (*pt == ALTSEP)
1049 *pt = SEP;
1050 if (namebuf[len-1] != SEP)
1051 namebuf[len++] = SEP;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001052 strcpy(namebuf + len, "*.*");
1053
Barry Warsaw53699e91996-12-10 23:23:01 +00001054 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001055 return NULL;
1056
1057 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001058 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1059 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001060 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001061 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001062 }
1063 do {
1064 if (ep.name[0] == '.' &&
1065 (ep.name[1] == '\0' ||
1066 ep.name[1] == '.' &&
1067 ep.name[2] == '\0'))
1068 continue;
1069 strcpy(namebuf, ep.name);
1070 for (pt = namebuf; *pt; pt++)
1071 if (isupper(*pt))
1072 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001073 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001074 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001075 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001076 d = NULL;
1077 break;
1078 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001079 if (PyList_Append(d, v) != 0) {
1080 Py_DECREF(v);
1081 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001082 d = NULL;
1083 break;
1084 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001085 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001086 } while (_dos_findnext(&ep) == 0);
1087
1088 return d;
1089
Tim Peters0bb44a42000-09-15 07:44:49 +00001090#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001091
1092#ifndef MAX_PATH
1093#define MAX_PATH CCHMAXPATH
1094#endif
1095 char *name, *pt;
1096 int len;
1097 PyObject *d, *v;
1098 char namebuf[MAX_PATH+5];
1099 HDIR hdir = 1;
1100 ULONG srchcnt = 1;
1101 FILEFINDBUF3 ep;
1102 APIRET rc;
1103
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001104 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001105 return NULL;
1106 if (len >= MAX_PATH) {
1107 PyErr_SetString(PyExc_ValueError, "path too long");
1108 return NULL;
1109 }
1110 strcpy(namebuf, name);
1111 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001112 if (*pt == ALTSEP)
1113 *pt = SEP;
1114 if (namebuf[len-1] != SEP)
1115 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001116 strcpy(namebuf + len, "*.*");
1117
1118 if ((d = PyList_New(0)) == NULL)
1119 return NULL;
1120
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001121 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1122 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001123 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001124 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1125 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1126 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001127
1128 if (rc != NO_ERROR) {
1129 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001130 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001131 }
1132
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001133 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001134 do {
1135 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001136 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001137 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001138
1139 strcpy(namebuf, ep.achName);
1140
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001141 /* Leave Case of Name Alone -- In Native Form */
1142 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001143
1144 v = PyString_FromString(namebuf);
1145 if (v == NULL) {
1146 Py_DECREF(d);
1147 d = NULL;
1148 break;
1149 }
1150 if (PyList_Append(d, v) != 0) {
1151 Py_DECREF(v);
1152 Py_DECREF(d);
1153 d = NULL;
1154 break;
1155 }
1156 Py_DECREF(v);
1157 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1158 }
1159
1160 return d;
1161#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001162
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001163 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001164 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001165 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001166 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001167 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001169 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001170 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001171 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001172 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001173 closedir(dirp);
1174 return NULL;
1175 }
1176 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001177 if (ep->d_name[0] == '.' &&
1178 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001179 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001180 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001181 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001183 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184 d = NULL;
1185 break;
1186 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001187 if (PyList_Append(d, v) != 0) {
1188 Py_DECREF(v);
1189 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001190 d = NULL;
1191 break;
1192 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001193 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001194 }
1195 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001196
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001197 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001198
Tim Peters0bb44a42000-09-15 07:44:49 +00001199#endif /* which OS */
1200} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001201
Mark Hammondef8b6542001-05-13 08:04:26 +00001202#ifdef MS_WIN32
1203/* A helper function for abspath on win32 */
1204static PyObject *
1205posix__getfullpathname(PyObject *self, PyObject *args)
1206{
1207 /* assume encoded strings wont more than double no of chars */
1208 char inbuf[MAX_PATH*2];
1209 char *inbufp = inbuf;
1210 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1211 char outbuf[MAX_PATH*2];
1212 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001213 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1214 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001215 &insize))
1216 return NULL;
1217 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1218 outbuf, &temp))
1219 return win32_error("GetFullPathName", inbuf);
1220 return PyString_FromString(outbuf);
1221} /* end of posix__getfullpathname */
1222#endif /* MS_WIN32 */
1223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001224static char posix_mkdir__doc__[] =
1225"mkdir(path [, mode=0777]) -> None\n\
1226Create a directory.";
1227
Barry Warsaw53699e91996-12-10 23:23:01 +00001228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001229posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001230{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001231 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001232 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001233 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001234 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001235 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001236 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001237 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001238#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001239 res = mkdir(path);
1240#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001241 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001242#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001243 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001244 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001245 return posix_error_with_allocated_filename(path);
1246 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001247 Py_INCREF(Py_None);
1248 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249}
1250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001251
Guido van Rossumb6775db1994-08-01 11:34:53 +00001252#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001253#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1254#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1255#include <sys/resource.h>
1256#endif
1257#endif
1258
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001259static char posix_nice__doc__[] =
1260"nice(inc) -> new_priority\n\
1261Decrease the priority of process and return new priority.";
1262
Barry Warsaw53699e91996-12-10 23:23:01 +00001263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001264posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001265{
1266 int increment, value;
1267
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001268 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001269 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001270
1271 /* There are two flavours of 'nice': one that returns the new
1272 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001273 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1274 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001275
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001276 If we are of the nice family that returns the new priority, we
1277 need to clear errno before the call, and check if errno is filled
1278 before calling posix_error() on a returnvalue of -1, because the
1279 -1 may be the actual new priority! */
1280
1281 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001282 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001283#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001284 if (value == 0)
1285 value = getpriority(PRIO_PROCESS, 0);
1286#endif
1287 if (value == -1 && errno != 0)
1288 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001289 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001290 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001291}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001292#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001294
1295static char posix_rename__doc__[] =
1296"rename(old, new) -> None\n\
1297Rename a file or directory.";
1298
Barry Warsaw53699e91996-12-10 23:23:01 +00001299static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001300posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301{
Mark Hammondef8b6542001-05-13 08:04:26 +00001302 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303}
1304
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001305
1306static char posix_rmdir__doc__[] =
1307"rmdir(path) -> None\n\
1308Remove a directory.";
1309
Barry Warsaw53699e91996-12-10 23:23:01 +00001310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001311posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312{
Mark Hammondef8b6542001-05-13 08:04:26 +00001313 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314}
1315
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001316
1317static char posix_stat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00001318"stat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
1319 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001320Perform a stat system call on the given path.";
1321
Barry Warsaw53699e91996-12-10 23:23:01 +00001322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001323posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001324{
Mark Hammondef8b6542001-05-13 08:04:26 +00001325 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326}
1327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001328
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001329#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001330static char posix_system__doc__[] =
1331"system(command) -> exit_status\n\
1332Execute the command (a string) in a subshell.";
1333
Barry Warsaw53699e91996-12-10 23:23:01 +00001334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001335posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001336{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001337 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001338 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001339 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001340 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001341 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001342 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001343 Py_END_ALLOW_THREADS
1344 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001345}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001346#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001348
1349static char posix_umask__doc__[] =
1350"umask(new_mask) -> old_mask\n\
1351Set the current numeric umask and return the previous umask.";
1352
Barry Warsaw53699e91996-12-10 23:23:01 +00001353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001354posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001355{
1356 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001357 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001358 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001359 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001360 if (i < 0)
1361 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001362 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001363}
1364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001365
1366static char posix_unlink__doc__[] =
1367"unlink(path) -> None\n\
1368Remove a file (same as remove(path)).";
1369
1370static char posix_remove__doc__[] =
1371"remove(path) -> None\n\
1372Remove a file (same as unlink(path)).";
1373
Barry Warsaw53699e91996-12-10 23:23:01 +00001374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001375posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001376{
Mark Hammondef8b6542001-05-13 08:04:26 +00001377 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001378}
1379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001380
Guido van Rossumb6775db1994-08-01 11:34:53 +00001381#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001382static char posix_uname__doc__[] =
1383"uname() -> (sysname, nodename, release, version, machine)\n\
1384Return a tuple identifying the current operating system.";
1385
Barry Warsaw53699e91996-12-10 23:23:01 +00001386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001387posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001388{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001389 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001390 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001391 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001392 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001393 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001394 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001395 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001396 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001397 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001398 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001399 u.sysname,
1400 u.nodename,
1401 u.release,
1402 u.version,
1403 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001404}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001405#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001407
1408static char posix_utime__doc__[] =
1409"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001410utime(path, None) -> None\n\
1411Set the access and modified time of the file to the given values. If the\n\
1412second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001413
Barry Warsaw53699e91996-12-10 23:23:01 +00001414static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001415posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001416{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001417 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001418 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001419 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001420 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001421
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001422/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001423#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001424 struct utimbuf buf;
1425#define ATIME buf.actime
1426#define MTIME buf.modtime
1427#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001428#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001429 time_t buf[2];
1430#define ATIME buf[0]
1431#define MTIME buf[1]
1432#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001433#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001434
Barry Warsaw3cef8562000-05-01 16:17:24 +00001435 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001436 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001437 if (arg == Py_None) {
1438 /* optional time values not given */
1439 Py_BEGIN_ALLOW_THREADS
1440 res = utime(path, NULL);
1441 Py_END_ALLOW_THREADS
1442 }
1443 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1444 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001445 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001446 return NULL;
1447 }
1448 else {
1449 ATIME = atime;
1450 MTIME = mtime;
1451 Py_BEGIN_ALLOW_THREADS
1452 res = utime(path, UTIME_ARG);
1453 Py_END_ALLOW_THREADS
1454 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001455 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001456 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001457 Py_INCREF(Py_None);
1458 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001459#undef UTIME_ARG
1460#undef ATIME
1461#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001462}
1463
Guido van Rossum85e3b011991-06-03 12:42:10 +00001464
Guido van Rossum3b066191991-06-04 19:40:25 +00001465/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001466
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001467static char posix__exit__doc__[] =
1468"_exit(status)\n\
1469Exit to the system with specified status, without normal exit processing.";
1470
Barry Warsaw53699e91996-12-10 23:23:01 +00001471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001472posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001473{
1474 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001475 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001476 return NULL;
1477 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001478 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001479}
1480
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001481
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001482#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001483static char posix_execv__doc__[] =
1484"execv(path, args)\n\
1485Execute an executable path with arguments, replacing current process.\n\
1486\n\
1487 path: path of executable file\n\
1488 args: tuple or list of strings";
1489
Barry Warsaw53699e91996-12-10 23:23:01 +00001490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001491posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001492{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001493 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001494 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001495 char **argvlist;
1496 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001497 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001498
Guido van Rossum89b33251993-10-22 14:26:06 +00001499 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001500 argv is a list or tuple of strings. */
1501
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001502 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001503 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001504 if (PyList_Check(argv)) {
1505 argc = PyList_Size(argv);
1506 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001507 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001508 else if (PyTuple_Check(argv)) {
1509 argc = PyTuple_Size(argv);
1510 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001511 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001512 else {
Fred Drake661ea262000-10-24 19:57:45 +00001513 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001514 return NULL;
1515 }
1516
1517 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001518 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001519 return NULL;
1520 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001521
Barry Warsaw53699e91996-12-10 23:23:01 +00001522 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001523 if (argvlist == NULL)
1524 return NULL;
1525 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001526 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1527 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001528 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001529 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001530 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001531
Guido van Rossum85e3b011991-06-03 12:42:10 +00001532 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001533 }
1534 argvlist[argc] = NULL;
1535
Guido van Rossumb6775db1994-08-01 11:34:53 +00001536#ifdef BAD_EXEC_PROTOTYPES
1537 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001538#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001539 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001540#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001541
Guido van Rossum85e3b011991-06-03 12:42:10 +00001542 /* If we get here it's definitely an error */
1543
Barry Warsaw53699e91996-12-10 23:23:01 +00001544 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001545 return posix_error();
1546}
1547
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001548
1549static char posix_execve__doc__[] =
1550"execve(path, args, env)\n\
1551Execute a path with arguments and environment, replacing current process.\n\
1552\n\
1553 path: path of executable file\n\
1554 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001555 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001556
Barry Warsaw53699e91996-12-10 23:23:01 +00001557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001558posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001559{
1560 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001561 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001562 char **argvlist;
1563 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001564 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001565 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001566 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001567
1568 /* execve has three arguments: (path, argv, env), where
1569 argv is a list or tuple of strings and env is a dictionary
1570 like posix.environ. */
1571
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001572 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001573 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001574 if (PyList_Check(argv)) {
1575 argc = PyList_Size(argv);
1576 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001577 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001578 else if (PyTuple_Check(argv)) {
1579 argc = PyTuple_Size(argv);
1580 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001581 }
1582 else {
Fred Drake661ea262000-10-24 19:57:45 +00001583 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001584 return NULL;
1585 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001586 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001587 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001588 return NULL;
1589 }
1590
Guido van Rossum50422b42000-04-26 20:34:28 +00001591 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001592 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001593 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001594 return NULL;
1595 }
1596
Barry Warsaw53699e91996-12-10 23:23:01 +00001597 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001598 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001599 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001600 return NULL;
1601 }
1602 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001603 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001604 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001605 &argvlist[i]))
1606 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001607 goto fail_1;
1608 }
1609 }
1610 argvlist[argc] = NULL;
1611
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001612 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001613 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001614 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001615 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001616 goto fail_1;
1617 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001618 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001619 keys = PyMapping_Keys(env);
1620 vals = PyMapping_Values(env);
1621 if (!keys || !vals)
1622 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001623
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001624 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001625 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001626 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001627
1628 key = PyList_GetItem(keys, pos);
1629 val = PyList_GetItem(vals, pos);
1630 if (!key || !val)
1631 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001632
Fred Drake661ea262000-10-24 19:57:45 +00001633 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1634 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001635 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001636 goto fail_2;
1637 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001638
1639#if defined(PYOS_OS2)
1640 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1641 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1642#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001643 len = PyString_Size(key) + PyString_Size(val) + 2;
1644 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001645 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001646 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001647 goto fail_2;
1648 }
Tim Petersc8996f52001-12-03 20:41:00 +00001649 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001650 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001651#if defined(PYOS_OS2)
1652 }
1653#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001654 }
1655 envlist[envc] = 0;
1656
Guido van Rossumb6775db1994-08-01 11:34:53 +00001657
1658#ifdef BAD_EXEC_PROTOTYPES
1659 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001660#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001661 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001662#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001663
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001664 /* If we get here it's definitely an error */
1665
1666 (void) posix_error();
1667
1668 fail_2:
1669 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001670 PyMem_DEL(envlist[envc]);
1671 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001672 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001673 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001674 Py_XDECREF(vals);
1675 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001676 return NULL;
1677}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001678#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001680
Guido van Rossuma1065681999-01-25 23:20:23 +00001681#ifdef HAVE_SPAWNV
1682static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001683"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001684Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001685\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001686 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001687 path: path of executable file\n\
1688 args: tuple or list of strings";
1689
1690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001691posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001692{
1693 char *path;
1694 PyObject *argv;
1695 char **argvlist;
1696 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001697 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001698 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001699
1700 /* spawnv has three arguments: (mode, path, argv), where
1701 argv is a list or tuple of strings. */
1702
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001703 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001704 return NULL;
1705 if (PyList_Check(argv)) {
1706 argc = PyList_Size(argv);
1707 getitem = PyList_GetItem;
1708 }
1709 else if (PyTuple_Check(argv)) {
1710 argc = PyTuple_Size(argv);
1711 getitem = PyTuple_GetItem;
1712 }
1713 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001714 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001715 return NULL;
1716 }
1717
1718 argvlist = PyMem_NEW(char *, argc+1);
1719 if (argvlist == NULL)
1720 return NULL;
1721 for (i = 0; i < argc; i++) {
1722 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1723 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001724 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001725 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001726 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001727 }
1728 }
1729 argvlist[argc] = NULL;
1730
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001731#if defined(PYOS_OS2) && defined(PYCC_GCC)
1732 Py_BEGIN_ALLOW_THREADS
1733 spawnval = spawnv(mode, path, argvlist);
1734 Py_END_ALLOW_THREADS
1735#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001736 if (mode == _OLD_P_OVERLAY)
1737 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001738
Tim Peters25059d32001-12-07 20:35:43 +00001739 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001740 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001741 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001742#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001743
Guido van Rossuma1065681999-01-25 23:20:23 +00001744 PyMem_DEL(argvlist);
1745
Fred Drake699f3522000-06-29 21:12:41 +00001746 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001747 return posix_error();
1748 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001749#if SIZEOF_LONG == SIZEOF_VOID_P
1750 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001751#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001752 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001753#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001754}
1755
1756
1757static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001758"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001759Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001760\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001761 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001762 path: path of executable file\n\
1763 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001764 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001765
1766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001767posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001768{
1769 char *path;
1770 PyObject *argv, *env;
1771 char **argvlist;
1772 char **envlist;
1773 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1774 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001775 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001776 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001777
1778 /* spawnve has four arguments: (mode, path, argv, env), where
1779 argv is a list or tuple of strings and env is a dictionary
1780 like posix.environ. */
1781
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001782 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001783 return NULL;
1784 if (PyList_Check(argv)) {
1785 argc = PyList_Size(argv);
1786 getitem = PyList_GetItem;
1787 }
1788 else if (PyTuple_Check(argv)) {
1789 argc = PyTuple_Size(argv);
1790 getitem = PyTuple_GetItem;
1791 }
1792 else {
Fred Drake661ea262000-10-24 19:57:45 +00001793 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001794 return NULL;
1795 }
1796 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001797 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001798 return NULL;
1799 }
1800
1801 argvlist = PyMem_NEW(char *, argc+1);
1802 if (argvlist == NULL) {
1803 PyErr_NoMemory();
1804 return NULL;
1805 }
1806 for (i = 0; i < argc; i++) {
1807 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001808 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001809 &argvlist[i]))
1810 {
1811 goto fail_1;
1812 }
1813 }
1814 argvlist[argc] = NULL;
1815
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001816 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001817 envlist = PyMem_NEW(char *, i + 1);
1818 if (envlist == NULL) {
1819 PyErr_NoMemory();
1820 goto fail_1;
1821 }
1822 envc = 0;
1823 keys = PyMapping_Keys(env);
1824 vals = PyMapping_Values(env);
1825 if (!keys || !vals)
1826 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001827
Guido van Rossuma1065681999-01-25 23:20:23 +00001828 for (pos = 0; pos < i; pos++) {
1829 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001830 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001831
1832 key = PyList_GetItem(keys, pos);
1833 val = PyList_GetItem(vals, pos);
1834 if (!key || !val)
1835 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001836
Fred Drake661ea262000-10-24 19:57:45 +00001837 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1838 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001839 {
1840 goto fail_2;
1841 }
Tim Petersc8996f52001-12-03 20:41:00 +00001842 len = PyString_Size(key) + PyString_Size(val) + 2;
1843 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001844 if (p == NULL) {
1845 PyErr_NoMemory();
1846 goto fail_2;
1847 }
Tim Petersc8996f52001-12-03 20:41:00 +00001848 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001849 envlist[envc++] = p;
1850 }
1851 envlist[envc] = 0;
1852
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001853#if defined(PYOS_OS2) && defined(PYCC_GCC)
1854 Py_BEGIN_ALLOW_THREADS
1855 spawnval = spawnve(mode, path, argvlist, envlist);
1856 Py_END_ALLOW_THREADS
1857#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001858 if (mode == _OLD_P_OVERLAY)
1859 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001860
1861 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001862 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001863 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001864#endif
Tim Peters25059d32001-12-07 20:35:43 +00001865
Fred Drake699f3522000-06-29 21:12:41 +00001866 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001867 (void) posix_error();
1868 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001869#if SIZEOF_LONG == SIZEOF_VOID_P
1870 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001871#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001872 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001873#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001874
1875 fail_2:
1876 while (--envc >= 0)
1877 PyMem_DEL(envlist[envc]);
1878 PyMem_DEL(envlist);
1879 fail_1:
1880 PyMem_DEL(argvlist);
1881 Py_XDECREF(vals);
1882 Py_XDECREF(keys);
1883 return res;
1884}
1885#endif /* HAVE_SPAWNV */
1886
1887
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001888#ifdef HAVE_FORK1
1889static char posix_fork1__doc__[] =
1890"fork1() -> pid\n\
1891Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1892\n\
1893Return 0 to child process and PID of child to parent process.";
1894
1895static PyObject *
1896posix_fork1(self, args)
1897 PyObject *self;
1898 PyObject *args;
1899{
1900 int pid;
1901 if (!PyArg_ParseTuple(args, ":fork1"))
1902 return NULL;
1903 pid = fork1();
1904 if (pid == -1)
1905 return posix_error();
1906 PyOS_AfterFork();
1907 return PyInt_FromLong((long)pid);
1908}
1909#endif
1910
1911
Guido van Rossumad0ee831995-03-01 10:34:45 +00001912#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001913static char posix_fork__doc__[] =
1914"fork() -> pid\n\
1915Fork a child process.\n\
1916\n\
1917Return 0 to child process and PID of child to parent process.";
1918
Barry Warsaw53699e91996-12-10 23:23:01 +00001919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001920posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001921{
1922 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001923 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001924 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001925 pid = fork();
1926 if (pid == -1)
1927 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001928 if (pid == 0)
1929 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001930 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001931}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001932#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001933
Fred Drake8cef4cf2000-06-28 16:40:38 +00001934#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1935#ifdef HAVE_PTY_H
1936#include <pty.h>
1937#else
1938#ifdef HAVE_LIBUTIL_H
1939#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001940#endif /* HAVE_LIBUTIL_H */
1941#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001942#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001943
Thomas Wouters70c21a12000-07-14 14:28:33 +00001944#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001945static char posix_openpty__doc__[] =
1946"openpty() -> (master_fd, slave_fd)\n\
1947Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1948
1949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001950posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001951{
1952 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001953#ifndef HAVE_OPENPTY
1954 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001955#endif
1956
Fred Drake8cef4cf2000-06-28 16:40:38 +00001957 if (!PyArg_ParseTuple(args, ":openpty"))
1958 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001959
1960#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001961 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1962 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001963#else
1964 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1965 if (slave_name == NULL)
1966 return posix_error();
1967
1968 slave_fd = open(slave_name, O_RDWR);
1969 if (slave_fd < 0)
1970 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001971#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001972
Fred Drake8cef4cf2000-06-28 16:40:38 +00001973 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001974
Fred Drake8cef4cf2000-06-28 16:40:38 +00001975}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001976#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001977
1978#ifdef HAVE_FORKPTY
1979static char posix_forkpty__doc__[] =
1980"forkpty() -> (pid, master_fd)\n\
1981Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1982Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1983To both, return fd of newly opened pseudo-terminal.\n";
1984
1985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001986posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001987{
1988 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00001989
Fred Drake8cef4cf2000-06-28 16:40:38 +00001990 if (!PyArg_ParseTuple(args, ":forkpty"))
1991 return NULL;
1992 pid = forkpty(&master_fd, NULL, NULL, NULL);
1993 if (pid == -1)
1994 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001995 if (pid == 0)
1996 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001997 return Py_BuildValue("(ii)", pid, master_fd);
1998}
1999#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002000
Guido van Rossumad0ee831995-03-01 10:34:45 +00002001#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002002static char posix_getegid__doc__[] =
2003"getegid() -> egid\n\
2004Return the current process's effective group id.";
2005
Barry Warsaw53699e91996-12-10 23:23:01 +00002006static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002007posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002008{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002009 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002010 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002011 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002012}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002013#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002014
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002015
Guido van Rossumad0ee831995-03-01 10:34:45 +00002016#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002017static char posix_geteuid__doc__[] =
2018"geteuid() -> euid\n\
2019Return the current process's effective user id.";
2020
Barry Warsaw53699e91996-12-10 23:23:01 +00002021static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002022posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002023{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002024 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002025 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002026 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002027}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002028#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002030
Guido van Rossumad0ee831995-03-01 10:34:45 +00002031#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002032static char posix_getgid__doc__[] =
2033"getgid() -> gid\n\
2034Return the current process's group id.";
2035
Barry Warsaw53699e91996-12-10 23:23:01 +00002036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002037posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002038{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002039 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002040 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002041 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002042}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002043#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002044
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002045
2046static char posix_getpid__doc__[] =
2047"getpid() -> pid\n\
2048Return the current process id";
2049
Barry Warsaw53699e91996-12-10 23:23:01 +00002050static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002051posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002052{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002053 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002054 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002055 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002056}
2057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002058
Fred Drakec9680921999-12-13 16:37:25 +00002059#ifdef HAVE_GETGROUPS
2060static char posix_getgroups__doc__[] = "\
2061getgroups() -> list of group IDs\n\
2062Return list of supplemental group IDs for the process.";
2063
2064static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002065posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002066{
2067 PyObject *result = NULL;
2068
2069 if (PyArg_ParseTuple(args, ":getgroups")) {
2070#ifdef NGROUPS_MAX
2071#define MAX_GROUPS NGROUPS_MAX
2072#else
2073 /* defined to be 16 on Solaris7, so this should be a small number */
2074#define MAX_GROUPS 64
2075#endif
2076 gid_t grouplist[MAX_GROUPS];
2077 int n;
2078
2079 n = getgroups(MAX_GROUPS, grouplist);
2080 if (n < 0)
2081 posix_error();
2082 else {
2083 result = PyList_New(n);
2084 if (result != NULL) {
2085 PyObject *o;
2086 int i;
2087 for (i = 0; i < n; ++i) {
2088 o = PyInt_FromLong((long)grouplist[i]);
2089 if (o == NULL) {
2090 Py_DECREF(result);
2091 result = NULL;
2092 break;
2093 }
2094 PyList_SET_ITEM(result, i, o);
2095 }
2096 }
2097 }
2098 }
2099 return result;
2100}
2101#endif
2102
Guido van Rossumb6775db1994-08-01 11:34:53 +00002103#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002104static char posix_getpgrp__doc__[] =
2105"getpgrp() -> pgrp\n\
2106Return the current process group id.";
2107
Barry Warsaw53699e91996-12-10 23:23:01 +00002108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002109posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002110{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002111 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002112 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002113#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002114 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002115#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002116 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002117#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002118}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002119#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002121
Guido van Rossumb6775db1994-08-01 11:34:53 +00002122#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002123static char posix_setpgrp__doc__[] =
2124"setpgrp() -> None\n\
2125Make this process a session leader.";
2126
Barry Warsaw53699e91996-12-10 23:23:01 +00002127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002128posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002129{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002130 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002131 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002132#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002133 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002134#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002135 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002136#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002137 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002138 Py_INCREF(Py_None);
2139 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002140}
2141
Guido van Rossumb6775db1994-08-01 11:34:53 +00002142#endif /* HAVE_SETPGRP */
2143
Guido van Rossumad0ee831995-03-01 10:34:45 +00002144#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002145static char posix_getppid__doc__[] =
2146"getppid() -> ppid\n\
2147Return the parent's process id.";
2148
Barry Warsaw53699e91996-12-10 23:23:01 +00002149static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002150posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002151{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002152 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002153 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002154 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002155}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002156#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002157
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002158
Fred Drake12c6e2d1999-12-14 21:25:03 +00002159#ifdef HAVE_GETLOGIN
2160static char posix_getlogin__doc__[] = "\
2161getlogin() -> string\n\
2162Return the actual login name.";
2163
2164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002165posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002166{
2167 PyObject *result = NULL;
2168
2169 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002170 char *name;
2171 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002172
Fred Drakea30680b2000-12-06 21:24:28 +00002173 errno = 0;
2174 name = getlogin();
2175 if (name == NULL) {
2176 if (errno)
2177 posix_error();
2178 else
2179 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002180 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002181 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002182 else
2183 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002184 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002185 }
2186 return result;
2187}
2188#endif
2189
Guido van Rossumad0ee831995-03-01 10:34:45 +00002190#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002191static char posix_getuid__doc__[] =
2192"getuid() -> uid\n\
2193Return the current process's user id.";
2194
Barry Warsaw53699e91996-12-10 23:23:01 +00002195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002196posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002197{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002198 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002199 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002200 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002201}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002202#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002204
Guido van Rossumad0ee831995-03-01 10:34:45 +00002205#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002206static char posix_kill__doc__[] =
2207"kill(pid, sig) -> None\n\
2208Kill a process with a signal.";
2209
Barry Warsaw53699e91996-12-10 23:23:01 +00002210static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002211posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002212{
2213 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002214 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002215 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002216#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002217 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2218 APIRET rc;
2219 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002220 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002221
2222 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2223 APIRET rc;
2224 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002225 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002226
2227 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002228 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002229#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002230 if (kill(pid, sig) == -1)
2231 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002232#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002233 Py_INCREF(Py_None);
2234 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002235}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002236#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002237
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002238#ifdef HAVE_KILLPG
2239static char posix_killpg__doc__[] =
2240"killpg(pgid, sig) -> None\n\
2241Kill a process group with a signal.";
2242
2243static PyObject *
2244posix_killpg(PyObject *self, PyObject *args)
2245{
2246 int pgid, sig;
2247 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2248 return NULL;
2249 if (killpg(pgid, sig) == -1)
2250 return posix_error();
2251 Py_INCREF(Py_None);
2252 return Py_None;
2253}
2254#endif
2255
Guido van Rossumc0125471996-06-28 18:55:32 +00002256#ifdef HAVE_PLOCK
2257
2258#ifdef HAVE_SYS_LOCK_H
2259#include <sys/lock.h>
2260#endif
2261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002262static char posix_plock__doc__[] =
2263"plock(op) -> None\n\
2264Lock program segments into memory.";
2265
Barry Warsaw53699e91996-12-10 23:23:01 +00002266static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002267posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002268{
2269 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002270 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002271 return NULL;
2272 if (plock(op) == -1)
2273 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002274 Py_INCREF(Py_None);
2275 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002276}
2277#endif
2278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002280#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002281static char posix_popen__doc__[] =
2282"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2283Open a pipe to/from a command returning a file object.";
2284
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002285#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002286#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002287static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002288async_system(const char *command)
2289{
2290 char *p, errormsg[256], args[1024];
2291 RESULTCODES rcodes;
2292 APIRET rc;
2293 char *shell = getenv("COMSPEC");
2294 if (!shell)
2295 shell = "cmd";
2296
2297 strcpy(args, shell);
2298 p = &args[ strlen(args)+1 ];
2299 strcpy(p, "/c ");
2300 strcat(p, command);
2301 p += strlen(p) + 1;
2302 *p = '\0';
2303
2304 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002305 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002306 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002307 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002308 &rcodes, shell);
2309 return rc;
2310}
2311
Guido van Rossumd48f2521997-12-05 22:19:34 +00002312static FILE *
2313popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002314{
2315 HFILE rhan, whan;
2316 FILE *retfd = NULL;
2317 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2318
Guido van Rossumd48f2521997-12-05 22:19:34 +00002319 if (rc != NO_ERROR) {
2320 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002321 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002322 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002324 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2325 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002326
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002327 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2328 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002329
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002330 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2331 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002332
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002333 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002334 }
2335
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002336 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2337 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002338
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002339 if (rc == NO_ERROR)
2340 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2341
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002342 close(oldfd); /* And Close Saved STDOUT Handle */
2343 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002344
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002345 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2346 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002347
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002348 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2349 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002350
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002351 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2352 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002353
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002354 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002355 }
2356
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002357 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2358 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002359
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002360 if (rc == NO_ERROR)
2361 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2362
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002363 close(oldfd); /* And Close Saved STDIN Handle */
2364 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002365
Guido van Rossumd48f2521997-12-05 22:19:34 +00002366 } else {
2367 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002368 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002369 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002370}
2371
2372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002373posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002374{
2375 char *name;
2376 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002377 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002378 FILE *fp;
2379 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002380 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002381 return NULL;
2382 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002383 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002384 Py_END_ALLOW_THREADS
2385 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002386 return os2_error(err);
2387
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002388 f = PyFile_FromFile(fp, name, mode, fclose);
2389 if (f != NULL)
2390 PyFile_SetBufSize(f, bufsize);
2391 return f;
2392}
2393
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002394#elif defined(PYCC_GCC)
2395
2396/* standard posix version of popen() support */
2397static PyObject *
2398posix_popen(PyObject *self, PyObject *args)
2399{
2400 char *name;
2401 char *mode = "r";
2402 int bufsize = -1;
2403 FILE *fp;
2404 PyObject *f;
2405 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2406 return NULL;
2407 Py_BEGIN_ALLOW_THREADS
2408 fp = popen(name, mode);
2409 Py_END_ALLOW_THREADS
2410 if (fp == NULL)
2411 return posix_error();
2412 f = PyFile_FromFile(fp, name, mode, pclose);
2413 if (f != NULL)
2414 PyFile_SetBufSize(f, bufsize);
2415 return f;
2416}
2417
2418/* fork() under OS/2 has lots'o'warts
2419 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2420 * most of this code is a ripoff of the win32 code, but using the
2421 * capabilities of EMX's C library routines
2422 */
2423
2424/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2425#define POPEN_1 1
2426#define POPEN_2 2
2427#define POPEN_3 3
2428#define POPEN_4 4
2429
2430static PyObject *_PyPopen(char *, int, int, int);
2431static int _PyPclose(FILE *file);
2432
2433/*
2434 * Internal dictionary mapping popen* file pointers to process handles,
2435 * for use when retrieving the process exit code. See _PyPclose() below
2436 * for more information on this dictionary's use.
2437 */
2438static PyObject *_PyPopenProcs = NULL;
2439
2440/* os2emx version of popen2()
2441 *
2442 * The result of this function is a pipe (file) connected to the
2443 * process's stdin, and a pipe connected to the process's stdout.
2444 */
2445
2446static PyObject *
2447os2emx_popen2(PyObject *self, PyObject *args)
2448{
2449 PyObject *f;
2450 int tm=0;
2451
2452 char *cmdstring;
2453 char *mode = "t";
2454 int bufsize = -1;
2455 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2456 return NULL;
2457
2458 if (*mode == 't')
2459 tm = O_TEXT;
2460 else if (*mode != 'b') {
2461 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2462 return NULL;
2463 } else
2464 tm = O_BINARY;
2465
2466 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2467
2468 return f;
2469}
2470
2471/*
2472 * Variation on os2emx.popen2
2473 *
2474 * The result of this function is 3 pipes - the process's stdin,
2475 * stdout and stderr
2476 */
2477
2478static PyObject *
2479os2emx_popen3(PyObject *self, PyObject *args)
2480{
2481 PyObject *f;
2482 int tm = 0;
2483
2484 char *cmdstring;
2485 char *mode = "t";
2486 int bufsize = -1;
2487 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2488 return NULL;
2489
2490 if (*mode == 't')
2491 tm = O_TEXT;
2492 else if (*mode != 'b') {
2493 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2494 return NULL;
2495 } else
2496 tm = O_BINARY;
2497
2498 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2499
2500 return f;
2501}
2502
2503/*
2504 * Variation on os2emx.popen2
2505 *
2506 * The result of this function is 2 pipes - the processes stdin,
2507 * and stdout+stderr combined as a single pipe.
2508 */
2509
2510static PyObject *
2511os2emx_popen4(PyObject *self, PyObject *args)
2512{
2513 PyObject *f;
2514 int tm = 0;
2515
2516 char *cmdstring;
2517 char *mode = "t";
2518 int bufsize = -1;
2519 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2520 return NULL;
2521
2522 if (*mode == 't')
2523 tm = O_TEXT;
2524 else if (*mode != 'b') {
2525 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2526 return NULL;
2527 } else
2528 tm = O_BINARY;
2529
2530 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2531
2532 return f;
2533}
2534
2535/* a couple of structures for convenient handling of multiple
2536 * file handles and pipes
2537 */
2538struct file_ref
2539{
2540 int handle;
2541 int flags;
2542};
2543
2544struct pipe_ref
2545{
2546 int rd;
2547 int wr;
2548};
2549
2550/* The following code is derived from the win32 code */
2551
2552static PyObject *
2553_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2554{
2555 struct file_ref stdio[3];
2556 struct pipe_ref p_fd[3];
2557 FILE *p_s[3];
2558 int file_count, i, pipe_err, pipe_pid;
2559 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2560 PyObject *f, *p_f[3];
2561
2562 /* file modes for subsequent fdopen's on pipe handles */
2563 if (mode == O_TEXT)
2564 {
2565 rd_mode = "rt";
2566 wr_mode = "wt";
2567 }
2568 else
2569 {
2570 rd_mode = "rb";
2571 wr_mode = "wb";
2572 }
2573
2574 /* prepare shell references */
2575 if ((shell = getenv("EMXSHELL")) == NULL)
2576 if ((shell = getenv("COMSPEC")) == NULL)
2577 {
2578 errno = ENOENT;
2579 return posix_error();
2580 }
2581
2582 sh_name = _getname(shell);
2583 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2584 opt = "/c";
2585 else
2586 opt = "-c";
2587
2588 /* save current stdio fds + their flags, and set not inheritable */
2589 i = pipe_err = 0;
2590 while (pipe_err >= 0 && i < 3)
2591 {
2592 pipe_err = stdio[i].handle = dup(i);
2593 stdio[i].flags = fcntl(i, F_GETFD, 0);
2594 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2595 i++;
2596 }
2597 if (pipe_err < 0)
2598 {
2599 /* didn't get them all saved - clean up and bail out */
2600 int saved_err = errno;
2601 while (i-- > 0)
2602 {
2603 close(stdio[i].handle);
2604 }
2605 errno = saved_err;
2606 return posix_error();
2607 }
2608
2609 /* create pipe ends */
2610 file_count = 2;
2611 if (n == POPEN_3)
2612 file_count = 3;
2613 i = pipe_err = 0;
2614 while ((pipe_err == 0) && (i < file_count))
2615 pipe_err = pipe((int *)&p_fd[i++]);
2616 if (pipe_err < 0)
2617 {
2618 /* didn't get them all made - clean up and bail out */
2619 while (i-- > 0)
2620 {
2621 close(p_fd[i].wr);
2622 close(p_fd[i].rd);
2623 }
2624 errno = EPIPE;
2625 return posix_error();
2626 }
2627
2628 /* change the actual standard IO streams over temporarily,
2629 * making the retained pipe ends non-inheritable
2630 */
2631 pipe_err = 0;
2632
2633 /* - stdin */
2634 if (dup2(p_fd[0].rd, 0) == 0)
2635 {
2636 close(p_fd[0].rd);
2637 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2638 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2639 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2640 {
2641 close(p_fd[0].wr);
2642 pipe_err = -1;
2643 }
2644 }
2645 else
2646 {
2647 pipe_err = -1;
2648 }
2649
2650 /* - stdout */
2651 if (pipe_err == 0)
2652 {
2653 if (dup2(p_fd[1].wr, 1) == 1)
2654 {
2655 close(p_fd[1].wr);
2656 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2657 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2658 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2659 {
2660 close(p_fd[1].rd);
2661 pipe_err = -1;
2662 }
2663 }
2664 else
2665 {
2666 pipe_err = -1;
2667 }
2668 }
2669
2670 /* - stderr, as required */
2671 if (pipe_err == 0)
2672 switch (n)
2673 {
2674 case POPEN_3:
2675 {
2676 if (dup2(p_fd[2].wr, 2) == 2)
2677 {
2678 close(p_fd[2].wr);
2679 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2680 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2681 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2682 {
2683 close(p_fd[2].rd);
2684 pipe_err = -1;
2685 }
2686 }
2687 else
2688 {
2689 pipe_err = -1;
2690 }
2691 break;
2692 }
2693
2694 case POPEN_4:
2695 {
2696 if (dup2(1, 2) != 2)
2697 {
2698 pipe_err = -1;
2699 }
2700 break;
2701 }
2702 }
2703
2704 /* spawn the child process */
2705 if (pipe_err == 0)
2706 {
2707 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2708 if (pipe_pid == -1)
2709 {
2710 pipe_err = -1;
2711 }
2712 else
2713 {
2714 /* save the PID into the FILE structure
2715 * NOTE: this implementation doesn't actually
2716 * take advantage of this, but do it for
2717 * completeness - AIM Apr01
2718 */
2719 for (i = 0; i < file_count; i++)
2720 p_s[i]->_pid = pipe_pid;
2721 }
2722 }
2723
2724 /* reset standard IO to normal */
2725 for (i = 0; i < 3; i++)
2726 {
2727 dup2(stdio[i].handle, i);
2728 fcntl(i, F_SETFD, stdio[i].flags);
2729 close(stdio[i].handle);
2730 }
2731
2732 /* if any remnant problems, clean up and bail out */
2733 if (pipe_err < 0)
2734 {
2735 for (i = 0; i < 3; i++)
2736 {
2737 close(p_fd[i].rd);
2738 close(p_fd[i].wr);
2739 }
2740 errno = EPIPE;
2741 return posix_error_with_filename(cmdstring);
2742 }
2743
2744 /* build tuple of file objects to return */
2745 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2746 PyFile_SetBufSize(p_f[0], bufsize);
2747 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2748 PyFile_SetBufSize(p_f[1], bufsize);
2749 if (n == POPEN_3)
2750 {
2751 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2752 PyFile_SetBufSize(p_f[0], bufsize);
2753 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2754 }
2755 else
2756 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2757
2758 /*
2759 * Insert the files we've created into the process dictionary
2760 * all referencing the list with the process handle and the
2761 * initial number of files (see description below in _PyPclose).
2762 * Since if _PyPclose later tried to wait on a process when all
2763 * handles weren't closed, it could create a deadlock with the
2764 * child, we spend some energy here to try to ensure that we
2765 * either insert all file handles into the dictionary or none
2766 * at all. It's a little clumsy with the various popen modes
2767 * and variable number of files involved.
2768 */
2769 if (!_PyPopenProcs)
2770 {
2771 _PyPopenProcs = PyDict_New();
2772 }
2773
2774 if (_PyPopenProcs)
2775 {
2776 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2777 int ins_rc[3];
2778
2779 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2780 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2781
2782 procObj = PyList_New(2);
2783 pidObj = PyInt_FromLong((long) pipe_pid);
2784 intObj = PyInt_FromLong((long) file_count);
2785
2786 if (procObj && pidObj && intObj)
2787 {
2788 PyList_SetItem(procObj, 0, pidObj);
2789 PyList_SetItem(procObj, 1, intObj);
2790
2791 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2792 if (fileObj[0])
2793 {
2794 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2795 fileObj[0],
2796 procObj);
2797 }
2798 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2799 if (fileObj[1])
2800 {
2801 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2802 fileObj[1],
2803 procObj);
2804 }
2805 if (file_count >= 3)
2806 {
2807 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2808 if (fileObj[2])
2809 {
2810 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2811 fileObj[2],
2812 procObj);
2813 }
2814 }
2815
2816 if (ins_rc[0] < 0 || !fileObj[0] ||
2817 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2818 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2819 {
2820 /* Something failed - remove any dictionary
2821 * entries that did make it.
2822 */
2823 if (!ins_rc[0] && fileObj[0])
2824 {
2825 PyDict_DelItem(_PyPopenProcs,
2826 fileObj[0]);
2827 }
2828 if (!ins_rc[1] && fileObj[1])
2829 {
2830 PyDict_DelItem(_PyPopenProcs,
2831 fileObj[1]);
2832 }
2833 if (!ins_rc[2] && fileObj[2])
2834 {
2835 PyDict_DelItem(_PyPopenProcs,
2836 fileObj[2]);
2837 }
2838 }
2839 }
2840
2841 /*
2842 * Clean up our localized references for the dictionary keys
2843 * and value since PyDict_SetItem will Py_INCREF any copies
2844 * that got placed in the dictionary.
2845 */
2846 Py_XDECREF(procObj);
2847 Py_XDECREF(fileObj[0]);
2848 Py_XDECREF(fileObj[1]);
2849 Py_XDECREF(fileObj[2]);
2850 }
2851
2852 /* Child is launched. */
2853 return f;
2854}
2855
2856/*
2857 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2858 * exit code for the child process and return as a result of the close.
2859 *
2860 * This function uses the _PyPopenProcs dictionary in order to map the
2861 * input file pointer to information about the process that was
2862 * originally created by the popen* call that created the file pointer.
2863 * The dictionary uses the file pointer as a key (with one entry
2864 * inserted for each file returned by the original popen* call) and a
2865 * single list object as the value for all files from a single call.
2866 * The list object contains the Win32 process handle at [0], and a file
2867 * count at [1], which is initialized to the total number of file
2868 * handles using that list.
2869 *
2870 * This function closes whichever handle it is passed, and decrements
2871 * the file count in the dictionary for the process handle pointed to
2872 * by this file. On the last close (when the file count reaches zero),
2873 * this function will wait for the child process and then return its
2874 * exit code as the result of the close() operation. This permits the
2875 * files to be closed in any order - it is always the close() of the
2876 * final handle that will return the exit code.
2877 */
2878
2879 /* RED_FLAG 31-Aug-2000 Tim
2880 * This is always called (today!) between a pair of
2881 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2882 * macros. So the thread running this has no valid thread state, as
2883 * far as Python is concerned. However, this calls some Python API
2884 * functions that cannot be called safely without a valid thread
2885 * state, in particular PyDict_GetItem.
2886 * As a temporary hack (although it may last for years ...), we
2887 * *rely* on not having a valid thread state in this function, in
2888 * order to create our own "from scratch".
2889 * This will deadlock if _PyPclose is ever called by a thread
2890 * holding the global lock.
2891 * (The OS/2 EMX thread support appears to cover the case where the
2892 * lock is already held - AIM Apr01)
2893 */
2894
2895static int _PyPclose(FILE *file)
2896{
2897 int result;
2898 int exit_code;
2899 int pipe_pid;
2900 PyObject *procObj, *pidObj, *intObj, *fileObj;
2901 int file_count;
2902#ifdef WITH_THREAD
2903 PyInterpreterState* pInterpreterState;
2904 PyThreadState* pThreadState;
2905#endif
2906
2907 /* Close the file handle first, to ensure it can't block the
2908 * child from exiting if it's the last handle.
2909 */
2910 result = fclose(file);
2911
2912#ifdef WITH_THREAD
2913 /* Bootstrap a valid thread state into existence. */
2914 pInterpreterState = PyInterpreterState_New();
2915 if (!pInterpreterState) {
2916 /* Well, we're hosed now! We don't have a thread
2917 * state, so can't call a nice error routine, or raise
2918 * an exception. Just die.
2919 */
2920 Py_FatalError("unable to allocate interpreter state "
2921 "when closing popen object.");
2922 return -1; /* unreachable */
2923 }
2924 pThreadState = PyThreadState_New(pInterpreterState);
2925 if (!pThreadState) {
2926 Py_FatalError("unable to allocate thread state "
2927 "when closing popen object.");
2928 return -1; /* unreachable */
2929 }
2930 /* Grab the global lock. Note that this will deadlock if the
2931 * current thread already has the lock! (see RED_FLAG comments
2932 * before this function)
2933 */
2934 PyEval_RestoreThread(pThreadState);
2935#endif
2936
2937 if (_PyPopenProcs)
2938 {
2939 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2940 (procObj = PyDict_GetItem(_PyPopenProcs,
2941 fileObj)) != NULL &&
2942 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2943 (intObj = PyList_GetItem(procObj,1)) != NULL)
2944 {
2945 pipe_pid = (int) PyInt_AsLong(pidObj);
2946 file_count = (int) PyInt_AsLong(intObj);
2947
2948 if (file_count > 1)
2949 {
2950 /* Still other files referencing process */
2951 file_count--;
2952 PyList_SetItem(procObj,1,
2953 PyInt_FromLong((long) file_count));
2954 }
2955 else
2956 {
2957 /* Last file for this process */
2958 if (result != EOF &&
2959 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2960 {
2961 /* extract exit status */
2962 if (WIFEXITED(exit_code))
2963 {
2964 result = WEXITSTATUS(exit_code);
2965 }
2966 else
2967 {
2968 errno = EPIPE;
2969 result = -1;
2970 }
2971 }
2972 else
2973 {
2974 /* Indicate failure - this will cause the file object
2975 * to raise an I/O error and translate the last
2976 * error code from errno. We do have a problem with
2977 * last errors that overlap the normal errno table,
2978 * but that's a consistent problem with the file object.
2979 */
2980 result = -1;
2981 }
2982 }
2983
2984 /* Remove this file pointer from dictionary */
2985 PyDict_DelItem(_PyPopenProcs, fileObj);
2986
2987 if (PyDict_Size(_PyPopenProcs) == 0)
2988 {
2989 Py_DECREF(_PyPopenProcs);
2990 _PyPopenProcs = NULL;
2991 }
2992
2993 } /* if object retrieval ok */
2994
2995 Py_XDECREF(fileObj);
2996 } /* if _PyPopenProcs */
2997
2998#ifdef WITH_THREAD
2999 /* Tear down the thread & interpreter states.
3000 * Note that interpreter state clear & delete functions automatically
3001 * call the thread clear & delete functions, and indeed insist on
3002 * doing that themselves. The lock must be held during the clear, but
3003 * need not be held during the delete.
3004 */
3005 PyInterpreterState_Clear(pInterpreterState);
3006 PyEval_ReleaseThread(pThreadState);
3007 PyInterpreterState_Delete(pInterpreterState);
3008#endif
3009
3010 return result;
3011}
3012
3013#endif /* PYCC_??? */
3014
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003015#elif defined(MS_WIN32)
3016
3017/*
3018 * Portable 'popen' replacement for Win32.
3019 *
3020 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3021 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003022 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003023 */
3024
3025#include <malloc.h>
3026#include <io.h>
3027#include <fcntl.h>
3028
3029/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3030#define POPEN_1 1
3031#define POPEN_2 2
3032#define POPEN_3 3
3033#define POPEN_4 4
3034
3035static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003036static int _PyPclose(FILE *file);
3037
3038/*
3039 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003040 * for use when retrieving the process exit code. See _PyPclose() below
3041 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003042 */
3043static PyObject *_PyPopenProcs = NULL;
3044
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003045
3046/* popen that works from a GUI.
3047 *
3048 * The result of this function is a pipe (file) connected to the
3049 * processes stdin or stdout, depending on the requested mode.
3050 */
3051
3052static PyObject *
3053posix_popen(PyObject *self, PyObject *args)
3054{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003055 PyObject *f, *s;
3056 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003057
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003058 char *cmdstring;
3059 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003060 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003061 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003062 return NULL;
3063
3064 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003065
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003066 if (*mode == 'r')
3067 tm = _O_RDONLY;
3068 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003069 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003070 return NULL;
3071 } else
3072 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003073
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003074 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003075 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003076 return NULL;
3077 }
3078
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003079 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003080 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003081 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003082 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003083 else
3084 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3085
3086 return f;
3087}
3088
3089/* Variation on win32pipe.popen
3090 *
3091 * The result of this function is a pipe (file) connected to the
3092 * process's stdin, and a pipe connected to the process's stdout.
3093 */
3094
3095static PyObject *
3096win32_popen2(PyObject *self, PyObject *args)
3097{
3098 PyObject *f;
3099 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003100
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003101 char *cmdstring;
3102 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003103 int bufsize = -1;
3104 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003105 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003106
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003107 if (*mode == 't')
3108 tm = _O_TEXT;
3109 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003110 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003111 return NULL;
3112 } else
3113 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003114
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003115 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003116 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003117 return NULL;
3118 }
3119
3120 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003121
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003122 return f;
3123}
3124
3125/*
3126 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003127 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003128 * The result of this function is 3 pipes - the process's stdin,
3129 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003130 */
3131
3132static PyObject *
3133win32_popen3(PyObject *self, PyObject *args)
3134{
3135 PyObject *f;
3136 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003137
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003138 char *cmdstring;
3139 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003140 int bufsize = -1;
3141 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003142 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003143
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003144 if (*mode == 't')
3145 tm = _O_TEXT;
3146 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003147 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003148 return NULL;
3149 } else
3150 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003151
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003152 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003153 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003154 return NULL;
3155 }
3156
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003157 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003158
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003159 return f;
3160}
3161
3162/*
3163 * Variation on win32pipe.popen
3164 *
Tim Peters5aa91602002-01-30 05:46:57 +00003165 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003166 * and stdout+stderr combined as a single pipe.
3167 */
3168
3169static PyObject *
3170win32_popen4(PyObject *self, PyObject *args)
3171{
3172 PyObject *f;
3173 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003174
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003175 char *cmdstring;
3176 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003177 int bufsize = -1;
3178 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003179 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003180
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003181 if (*mode == 't')
3182 tm = _O_TEXT;
3183 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003184 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003185 return NULL;
3186 } else
3187 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003188
3189 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003190 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003191 return NULL;
3192 }
3193
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003194 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003195
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003196 return f;
3197}
3198
Mark Hammond08501372001-01-31 07:30:29 +00003199static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003200_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003201 HANDLE hStdin,
3202 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003203 HANDLE hStderr,
3204 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003205{
3206 PROCESS_INFORMATION piProcInfo;
3207 STARTUPINFO siStartInfo;
3208 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003209 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003210 int i;
3211 int x;
3212
3213 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003214 char *comshell;
3215
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003216 s1 = (char *)_alloca(i);
3217 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3218 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003219
3220 /* Explicitly check if we are using COMMAND.COM. If we are
3221 * then use the w9xpopen hack.
3222 */
3223 comshell = s1 + x;
3224 while (comshell >= s1 && *comshell != '\\')
3225 --comshell;
3226 ++comshell;
3227
3228 if (GetVersion() < 0x80000000 &&
3229 _stricmp(comshell, "command.com") != 0) {
3230 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003231 x = i + strlen(s3) + strlen(cmdstring) + 1;
3232 s2 = (char *)_alloca(x);
3233 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003234 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003235 }
3236 else {
3237 /*
Tim Peters402d5982001-08-27 06:37:48 +00003238 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3239 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003240 */
Mark Hammond08501372001-01-31 07:30:29 +00003241 char modulepath[_MAX_PATH];
3242 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003243 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3244 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003245 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003246 x = i+1;
3247 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003248 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003249 strncat(modulepath,
3250 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003251 (sizeof(modulepath)/sizeof(modulepath[0]))
3252 -strlen(modulepath));
3253 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003254 /* Eeek - file-not-found - possibly an embedding
3255 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003256 */
Tim Peters5aa91602002-01-30 05:46:57 +00003257 strncpy(modulepath,
3258 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003259 sizeof(modulepath)/sizeof(modulepath[0]));
3260 if (modulepath[strlen(modulepath)-1] != '\\')
3261 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003262 strncat(modulepath,
3263 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003264 (sizeof(modulepath)/sizeof(modulepath[0]))
3265 -strlen(modulepath));
3266 /* No where else to look - raise an easily identifiable
3267 error, rather than leaving Windows to report
3268 "file not found" - as the user is probably blissfully
3269 unaware this shim EXE is used, and it will confuse them.
3270 (well, it confused me for a while ;-)
3271 */
3272 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003273 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003274 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003275 "for popen to work with your shell "
3276 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003277 szConsoleSpawn);
3278 return FALSE;
3279 }
3280 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003281 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003282 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003283 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003284
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003285 s2 = (char *)_alloca(x);
3286 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003287 PyOS_snprintf(
3288 s2, x,
Mark Hammond08501372001-01-31 07:30:29 +00003289 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003290 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003291 s1,
3292 s3,
3293 cmdstring);
3294 }
3295 }
3296
3297 /* Could be an else here to try cmd.exe / command.com in the path
3298 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003299 else {
Tim Peters402d5982001-08-27 06:37:48 +00003300 PyErr_SetString(PyExc_RuntimeError,
3301 "Cannot locate a COMSPEC environment variable to "
3302 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003303 return FALSE;
3304 }
Tim Peters5aa91602002-01-30 05:46:57 +00003305
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003306 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3307 siStartInfo.cb = sizeof(STARTUPINFO);
3308 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3309 siStartInfo.hStdInput = hStdin;
3310 siStartInfo.hStdOutput = hStdout;
3311 siStartInfo.hStdError = hStderr;
3312 siStartInfo.wShowWindow = SW_HIDE;
3313
3314 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003315 s2,
3316 NULL,
3317 NULL,
3318 TRUE,
3319 CREATE_NEW_CONSOLE,
3320 NULL,
3321 NULL,
3322 &siStartInfo,
3323 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003324 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003325 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003326
Mark Hammondb37a3732000-08-14 04:47:33 +00003327 /* Return process handle */
3328 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003329 return TRUE;
3330 }
Tim Peters402d5982001-08-27 06:37:48 +00003331 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003332 return FALSE;
3333}
3334
3335/* The following code is based off of KB: Q190351 */
3336
3337static PyObject *
3338_PyPopen(char *cmdstring, int mode, int n)
3339{
3340 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3341 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003342 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003343
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003344 SECURITY_ATTRIBUTES saAttr;
3345 BOOL fSuccess;
3346 int fd1, fd2, fd3;
3347 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003348 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003349 PyObject *f;
3350
3351 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3352 saAttr.bInheritHandle = TRUE;
3353 saAttr.lpSecurityDescriptor = NULL;
3354
3355 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3356 return win32_error("CreatePipe", NULL);
3357
3358 /* Create new output read handle and the input write handle. Set
3359 * the inheritance properties to FALSE. Otherwise, the child inherits
3360 * the these handles; resulting in non-closeable handles to the pipes
3361 * being created. */
3362 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003363 GetCurrentProcess(), &hChildStdinWrDup, 0,
3364 FALSE,
3365 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003366 if (!fSuccess)
3367 return win32_error("DuplicateHandle", NULL);
3368
3369 /* Close the inheritable version of ChildStdin
3370 that we're using. */
3371 CloseHandle(hChildStdinWr);
3372
3373 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3374 return win32_error("CreatePipe", NULL);
3375
3376 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003377 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3378 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003379 if (!fSuccess)
3380 return win32_error("DuplicateHandle", NULL);
3381
3382 /* Close the inheritable version of ChildStdout
3383 that we're using. */
3384 CloseHandle(hChildStdoutRd);
3385
3386 if (n != POPEN_4) {
3387 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3388 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003389 fSuccess = DuplicateHandle(GetCurrentProcess(),
3390 hChildStderrRd,
3391 GetCurrentProcess(),
3392 &hChildStderrRdDup, 0,
3393 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003394 if (!fSuccess)
3395 return win32_error("DuplicateHandle", NULL);
3396 /* Close the inheritable version of ChildStdErr that we're using. */
3397 CloseHandle(hChildStderrRd);
3398 }
Tim Peters5aa91602002-01-30 05:46:57 +00003399
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003400 switch (n) {
3401 case POPEN_1:
3402 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3403 case _O_WRONLY | _O_TEXT:
3404 /* Case for writing to child Stdin in text mode. */
3405 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3406 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003407 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003408 PyFile_SetBufSize(f, 0);
3409 /* We don't care about these pipes anymore, so close them. */
3410 CloseHandle(hChildStdoutRdDup);
3411 CloseHandle(hChildStderrRdDup);
3412 break;
3413
3414 case _O_RDONLY | _O_TEXT:
3415 /* Case for reading from child Stdout in text mode. */
3416 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3417 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003418 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003419 PyFile_SetBufSize(f, 0);
3420 /* We don't care about these pipes anymore, so close them. */
3421 CloseHandle(hChildStdinWrDup);
3422 CloseHandle(hChildStderrRdDup);
3423 break;
3424
3425 case _O_RDONLY | _O_BINARY:
3426 /* Case for readinig from child Stdout in binary mode. */
3427 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3428 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003429 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003430 PyFile_SetBufSize(f, 0);
3431 /* We don't care about these pipes anymore, so close them. */
3432 CloseHandle(hChildStdinWrDup);
3433 CloseHandle(hChildStderrRdDup);
3434 break;
3435
3436 case _O_WRONLY | _O_BINARY:
3437 /* Case for writing to child Stdin in binary mode. */
3438 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3439 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003440 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003441 PyFile_SetBufSize(f, 0);
3442 /* We don't care about these pipes anymore, so close them. */
3443 CloseHandle(hChildStdoutRdDup);
3444 CloseHandle(hChildStderrRdDup);
3445 break;
3446 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003447 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003448 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003449
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003450 case POPEN_2:
3451 case POPEN_4:
3452 {
3453 char *m1, *m2;
3454 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003455
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003456 if (mode && _O_TEXT) {
3457 m1 = "r";
3458 m2 = "w";
3459 } else {
3460 m1 = "rb";
3461 m2 = "wb";
3462 }
3463
3464 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3465 f1 = _fdopen(fd1, m2);
3466 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3467 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003468 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003469 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003470 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003471 PyFile_SetBufSize(p2, 0);
3472
3473 if (n != 4)
3474 CloseHandle(hChildStderrRdDup);
3475
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003476 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003477 Py_XDECREF(p1);
3478 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003479 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003480 break;
3481 }
Tim Peters5aa91602002-01-30 05:46:57 +00003482
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003483 case POPEN_3:
3484 {
3485 char *m1, *m2;
3486 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003487
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003488 if (mode && _O_TEXT) {
3489 m1 = "r";
3490 m2 = "w";
3491 } else {
3492 m1 = "rb";
3493 m2 = "wb";
3494 }
3495
3496 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3497 f1 = _fdopen(fd1, m2);
3498 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3499 f2 = _fdopen(fd2, m1);
3500 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3501 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003502 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003503 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3504 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003505 PyFile_SetBufSize(p1, 0);
3506 PyFile_SetBufSize(p2, 0);
3507 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003508 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003509 Py_XDECREF(p1);
3510 Py_XDECREF(p2);
3511 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003512 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003513 break;
3514 }
3515 }
3516
3517 if (n == POPEN_4) {
3518 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003519 hChildStdinRd,
3520 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003521 hChildStdoutWr,
3522 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003523 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003524 }
3525 else {
3526 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003527 hChildStdinRd,
3528 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003529 hChildStderrWr,
3530 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003531 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003532 }
3533
Mark Hammondb37a3732000-08-14 04:47:33 +00003534 /*
3535 * Insert the files we've created into the process dictionary
3536 * all referencing the list with the process handle and the
3537 * initial number of files (see description below in _PyPclose).
3538 * Since if _PyPclose later tried to wait on a process when all
3539 * handles weren't closed, it could create a deadlock with the
3540 * child, we spend some energy here to try to ensure that we
3541 * either insert all file handles into the dictionary or none
3542 * at all. It's a little clumsy with the various popen modes
3543 * and variable number of files involved.
3544 */
3545 if (!_PyPopenProcs) {
3546 _PyPopenProcs = PyDict_New();
3547 }
3548
3549 if (_PyPopenProcs) {
3550 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3551 int ins_rc[3];
3552
3553 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3554 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3555
3556 procObj = PyList_New(2);
3557 hProcessObj = PyLong_FromVoidPtr(hProcess);
3558 intObj = PyInt_FromLong(file_count);
3559
3560 if (procObj && hProcessObj && intObj) {
3561 PyList_SetItem(procObj,0,hProcessObj);
3562 PyList_SetItem(procObj,1,intObj);
3563
3564 fileObj[0] = PyLong_FromVoidPtr(f1);
3565 if (fileObj[0]) {
3566 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3567 fileObj[0],
3568 procObj);
3569 }
3570 if (file_count >= 2) {
3571 fileObj[1] = PyLong_FromVoidPtr(f2);
3572 if (fileObj[1]) {
3573 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3574 fileObj[1],
3575 procObj);
3576 }
3577 }
3578 if (file_count >= 3) {
3579 fileObj[2] = PyLong_FromVoidPtr(f3);
3580 if (fileObj[2]) {
3581 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3582 fileObj[2],
3583 procObj);
3584 }
3585 }
3586
3587 if (ins_rc[0] < 0 || !fileObj[0] ||
3588 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3589 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3590 /* Something failed - remove any dictionary
3591 * entries that did make it.
3592 */
3593 if (!ins_rc[0] && fileObj[0]) {
3594 PyDict_DelItem(_PyPopenProcs,
3595 fileObj[0]);
3596 }
3597 if (!ins_rc[1] && fileObj[1]) {
3598 PyDict_DelItem(_PyPopenProcs,
3599 fileObj[1]);
3600 }
3601 if (!ins_rc[2] && fileObj[2]) {
3602 PyDict_DelItem(_PyPopenProcs,
3603 fileObj[2]);
3604 }
3605 }
3606 }
Tim Peters5aa91602002-01-30 05:46:57 +00003607
Mark Hammondb37a3732000-08-14 04:47:33 +00003608 /*
3609 * Clean up our localized references for the dictionary keys
3610 * and value since PyDict_SetItem will Py_INCREF any copies
3611 * that got placed in the dictionary.
3612 */
3613 Py_XDECREF(procObj);
3614 Py_XDECREF(fileObj[0]);
3615 Py_XDECREF(fileObj[1]);
3616 Py_XDECREF(fileObj[2]);
3617 }
3618
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003619 /* Child is launched. Close the parents copy of those pipe
3620 * handles that only the child should have open. You need to
3621 * make sure that no handles to the write end of the output pipe
3622 * are maintained in this process or else the pipe will not close
3623 * when the child process exits and the ReadFile will hang. */
3624
3625 if (!CloseHandle(hChildStdinRd))
3626 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003627
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003628 if (!CloseHandle(hChildStdoutWr))
3629 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003630
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003631 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3632 return win32_error("CloseHandle", NULL);
3633
3634 return f;
3635}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003636
3637/*
3638 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3639 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003640 *
3641 * This function uses the _PyPopenProcs dictionary in order to map the
3642 * input file pointer to information about the process that was
3643 * originally created by the popen* call that created the file pointer.
3644 * The dictionary uses the file pointer as a key (with one entry
3645 * inserted for each file returned by the original popen* call) and a
3646 * single list object as the value for all files from a single call.
3647 * The list object contains the Win32 process handle at [0], and a file
3648 * count at [1], which is initialized to the total number of file
3649 * handles using that list.
3650 *
3651 * This function closes whichever handle it is passed, and decrements
3652 * the file count in the dictionary for the process handle pointed to
3653 * by this file. On the last close (when the file count reaches zero),
3654 * this function will wait for the child process and then return its
3655 * exit code as the result of the close() operation. This permits the
3656 * files to be closed in any order - it is always the close() of the
3657 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003658 */
Tim Peters736aa322000-09-01 06:51:24 +00003659
3660 /* RED_FLAG 31-Aug-2000 Tim
3661 * This is always called (today!) between a pair of
3662 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3663 * macros. So the thread running this has no valid thread state, as
3664 * far as Python is concerned. However, this calls some Python API
3665 * functions that cannot be called safely without a valid thread
3666 * state, in particular PyDict_GetItem.
3667 * As a temporary hack (although it may last for years ...), we
3668 * *rely* on not having a valid thread state in this function, in
3669 * order to create our own "from scratch".
3670 * This will deadlock if _PyPclose is ever called by a thread
3671 * holding the global lock.
3672 */
3673
Fredrik Lundh56055a42000-07-23 19:47:12 +00003674static int _PyPclose(FILE *file)
3675{
Fredrik Lundh20318932000-07-26 17:29:12 +00003676 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003677 DWORD exit_code;
3678 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003679 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3680 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003681#ifdef WITH_THREAD
3682 PyInterpreterState* pInterpreterState;
3683 PyThreadState* pThreadState;
3684#endif
3685
Fredrik Lundh20318932000-07-26 17:29:12 +00003686 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003687 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003688 */
3689 result = fclose(file);
3690
Tim Peters736aa322000-09-01 06:51:24 +00003691#ifdef WITH_THREAD
3692 /* Bootstrap a valid thread state into existence. */
3693 pInterpreterState = PyInterpreterState_New();
3694 if (!pInterpreterState) {
3695 /* Well, we're hosed now! We don't have a thread
3696 * state, so can't call a nice error routine, or raise
3697 * an exception. Just die.
3698 */
3699 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003700 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003701 return -1; /* unreachable */
3702 }
3703 pThreadState = PyThreadState_New(pInterpreterState);
3704 if (!pThreadState) {
3705 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003706 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003707 return -1; /* unreachable */
3708 }
3709 /* Grab the global lock. Note that this will deadlock if the
3710 * current thread already has the lock! (see RED_FLAG comments
3711 * before this function)
3712 */
3713 PyEval_RestoreThread(pThreadState);
3714#endif
3715
Fredrik Lundh56055a42000-07-23 19:47:12 +00003716 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003717 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3718 (procObj = PyDict_GetItem(_PyPopenProcs,
3719 fileObj)) != NULL &&
3720 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3721 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3722
3723 hProcess = PyLong_AsVoidPtr(hProcessObj);
3724 file_count = PyInt_AsLong(intObj);
3725
3726 if (file_count > 1) {
3727 /* Still other files referencing process */
3728 file_count--;
3729 PyList_SetItem(procObj,1,
3730 PyInt_FromLong(file_count));
3731 } else {
3732 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003733 if (result != EOF &&
3734 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3735 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003736 /* Possible truncation here in 16-bit environments, but
3737 * real exit codes are just the lower byte in any event.
3738 */
3739 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003740 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003741 /* Indicate failure - this will cause the file object
3742 * to raise an I/O error and translate the last Win32
3743 * error code from errno. We do have a problem with
3744 * last errors that overlap the normal errno table,
3745 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003746 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003747 if (result != EOF) {
3748 /* If the error wasn't from the fclose(), then
3749 * set errno for the file object error handling.
3750 */
3751 errno = GetLastError();
3752 }
3753 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003754 }
3755
3756 /* Free up the native handle at this point */
3757 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003758 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003759
Mark Hammondb37a3732000-08-14 04:47:33 +00003760 /* Remove this file pointer from dictionary */
3761 PyDict_DelItem(_PyPopenProcs, fileObj);
3762
3763 if (PyDict_Size(_PyPopenProcs) == 0) {
3764 Py_DECREF(_PyPopenProcs);
3765 _PyPopenProcs = NULL;
3766 }
3767
3768 } /* if object retrieval ok */
3769
3770 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003771 } /* if _PyPopenProcs */
3772
Tim Peters736aa322000-09-01 06:51:24 +00003773#ifdef WITH_THREAD
3774 /* Tear down the thread & interpreter states.
3775 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003776 * call the thread clear & delete functions, and indeed insist on
3777 * doing that themselves. The lock must be held during the clear, but
3778 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003779 */
3780 PyInterpreterState_Clear(pInterpreterState);
3781 PyEval_ReleaseThread(pThreadState);
3782 PyInterpreterState_Delete(pInterpreterState);
3783#endif
3784
Fredrik Lundh56055a42000-07-23 19:47:12 +00003785 return result;
3786}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003787
3788#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003790posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003791{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003792 char *name;
3793 char *mode = "r";
3794 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003795 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003796 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003797 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003798 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003799 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003800 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003801 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003802 if (fp == NULL)
3803 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003804 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003805 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003806 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003807 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003808}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003809
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003810#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003811#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003812
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003813
Guido van Rossumb6775db1994-08-01 11:34:53 +00003814#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003815static char posix_setuid__doc__[] =
3816"setuid(uid) -> None\n\
3817Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003818static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003819posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003820{
3821 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003822 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003823 return NULL;
3824 if (setuid(uid) < 0)
3825 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003826 Py_INCREF(Py_None);
3827 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003828}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003829#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003830
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003831
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003832#ifdef HAVE_SETEUID
3833static char posix_seteuid__doc__[] =
3834"seteuid(uid) -> None\n\
3835Set the current process's effective user id.";
3836static PyObject *
3837posix_seteuid (PyObject *self, PyObject *args)
3838{
3839 int euid;
3840 if (!PyArg_ParseTuple(args, "i", &euid)) {
3841 return NULL;
3842 } else if (seteuid(euid) < 0) {
3843 return posix_error();
3844 } else {
3845 Py_INCREF(Py_None);
3846 return Py_None;
3847 }
3848}
3849#endif /* HAVE_SETEUID */
3850
3851#ifdef HAVE_SETEGID
3852static char posix_setegid__doc__[] =
3853"setegid(gid) -> None\n\
3854Set the current process's effective group id.";
3855static PyObject *
3856posix_setegid (PyObject *self, PyObject *args)
3857{
3858 int egid;
3859 if (!PyArg_ParseTuple(args, "i", &egid)) {
3860 return NULL;
3861 } else if (setegid(egid) < 0) {
3862 return posix_error();
3863 } else {
3864 Py_INCREF(Py_None);
3865 return Py_None;
3866 }
3867}
3868#endif /* HAVE_SETEGID */
3869
3870#ifdef HAVE_SETREUID
3871static char posix_setreuid__doc__[] =
3872"seteuid(ruid, euid) -> None\n\
3873Set the current process's real and effective user ids.";
3874static PyObject *
3875posix_setreuid (PyObject *self, PyObject *args)
3876{
3877 int ruid, euid;
3878 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3879 return NULL;
3880 } else if (setreuid(ruid, euid) < 0) {
3881 return posix_error();
3882 } else {
3883 Py_INCREF(Py_None);
3884 return Py_None;
3885 }
3886}
3887#endif /* HAVE_SETREUID */
3888
3889#ifdef HAVE_SETREGID
3890static char posix_setregid__doc__[] =
3891"setegid(rgid, egid) -> None\n\
3892Set the current process's real and effective group ids.";
3893static PyObject *
3894posix_setregid (PyObject *self, PyObject *args)
3895{
3896 int rgid, egid;
3897 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3898 return NULL;
3899 } else if (setregid(rgid, egid) < 0) {
3900 return posix_error();
3901 } else {
3902 Py_INCREF(Py_None);
3903 return Py_None;
3904 }
3905}
3906#endif /* HAVE_SETREGID */
3907
Guido van Rossumb6775db1994-08-01 11:34:53 +00003908#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003909static char posix_setgid__doc__[] =
3910"setgid(gid) -> None\n\
3911Set the current process's group id.";
3912
Barry Warsaw53699e91996-12-10 23:23:01 +00003913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003914posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003915{
3916 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003917 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003918 return NULL;
3919 if (setgid(gid) < 0)
3920 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003921 Py_INCREF(Py_None);
3922 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003923}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003924#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003925
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003926#ifdef HAVE_SETGROUPS
3927static char posix_setgroups__doc__[] =
3928"setgroups(list) -> None\n\
3929Set the groups of the current process to list.";
3930
3931static PyObject *
3932posix_setgroups(PyObject *self, PyObject *args)
3933{
3934 PyObject *groups;
3935 int i, len;
3936 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003937
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003938 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3939 return NULL;
3940 if (!PySequence_Check(groups)) {
3941 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3942 return NULL;
3943 }
3944 len = PySequence_Size(groups);
3945 if (len > MAX_GROUPS) {
3946 PyErr_SetString(PyExc_ValueError, "too many groups");
3947 return NULL;
3948 }
3949 for(i = 0; i < len; i++) {
3950 PyObject *elem;
3951 elem = PySequence_GetItem(groups, i);
3952 if (!elem)
3953 return NULL;
3954 if (!PyInt_Check(elem)) {
3955 PyErr_SetString(PyExc_TypeError,
3956 "groups must be integers");
3957 Py_DECREF(elem);
3958 return NULL;
3959 }
3960 /* XXX: check that value fits into gid_t. */
3961 grouplist[i] = PyInt_AsLong(elem);
3962 Py_DECREF(elem);
3963 }
3964
3965 if (setgroups(len, grouplist) < 0)
3966 return posix_error();
3967 Py_INCREF(Py_None);
3968 return Py_None;
3969}
3970#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003971
Guido van Rossumb6775db1994-08-01 11:34:53 +00003972#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003973static char posix_waitpid__doc__[] =
3974"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003975Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003976
Barry Warsaw53699e91996-12-10 23:23:01 +00003977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003978posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003979{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003980 int pid, options;
3981#ifdef UNION_WAIT
3982 union wait status;
3983#define status_i (status.w_status)
3984#else
3985 int status;
3986#define status_i status
3987#endif
3988 status_i = 0;
3989
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003990 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003991 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003992 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003993 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00003994 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003995 if (pid == -1)
3996 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003997 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003998 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003999}
4000
Tim Petersab034fa2002-02-01 11:27:43 +00004001#elif defined(HAVE_CWAIT)
4002
4003/* MS C has a variant of waitpid() that's usable for most purposes. */
4004static char posix_waitpid__doc__[] =
4005"waitpid(pid, options) -> (pid, status << 8)\n"
4006"Wait for completion of a given process. options is ignored on Windows.";
4007
4008static PyObject *
4009posix_waitpid(PyObject *self, PyObject *args)
4010{
4011 int pid, options;
4012 int status;
4013
4014 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4015 return NULL;
4016 Py_BEGIN_ALLOW_THREADS
4017 pid = _cwait(&status, pid, options);
4018 Py_END_ALLOW_THREADS
4019 if (pid == -1)
4020 return posix_error();
4021 else
4022 /* shift the status left a byte so this is more like the
4023 POSIX waitpid */
4024 return Py_BuildValue("ii", pid, status << 8);
4025}
4026#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004027
Guido van Rossumad0ee831995-03-01 10:34:45 +00004028#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004029static char posix_wait__doc__[] =
4030"wait() -> (pid, status)\n\
4031Wait for completion of a child process.";
4032
Barry Warsaw53699e91996-12-10 23:23:01 +00004033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004034posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004035{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004036 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004037#ifdef UNION_WAIT
4038 union wait status;
4039#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004040#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004041 int status;
4042#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004043#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004044 if (!PyArg_ParseTuple(args, ":wait"))
4045 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004046 status_i = 0;
4047 Py_BEGIN_ALLOW_THREADS
4048 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004049 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004050 if (pid == -1)
4051 return posix_error();
4052 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004053 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004054#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004055}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004056#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004058
4059static char posix_lstat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00004060"lstat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
4061 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004062Like stat(path), but do not follow symbolic links.";
4063
Barry Warsaw53699e91996-12-10 23:23:01 +00004064static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004065posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004066{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004067#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004068 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004069#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004070 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004071#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004072}
4073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004074
Guido van Rossumb6775db1994-08-01 11:34:53 +00004075#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004076static char posix_readlink__doc__[] =
4077"readlink(path) -> path\n\
4078Return a string representing the path to which the symbolic link points.";
4079
Barry Warsaw53699e91996-12-10 23:23:01 +00004080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004081posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004082{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004083 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004084 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004085 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004086 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004087 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004088 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004089 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004090 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004091 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004092 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004093 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004094}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004095#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004097
Guido van Rossumb6775db1994-08-01 11:34:53 +00004098#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004099static char posix_symlink__doc__[] =
4100"symlink(src, dst) -> None\n\
4101Create a symbolic link.";
4102
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004104posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004105{
Mark Hammondef8b6542001-05-13 08:04:26 +00004106 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004107}
4108#endif /* HAVE_SYMLINK */
4109
4110
4111#ifdef HAVE_TIMES
4112#ifndef HZ
4113#define HZ 60 /* Universal constant :-) */
4114#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004115
Guido van Rossumd48f2521997-12-05 22:19:34 +00004116#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4117static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004118system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004119{
4120 ULONG value = 0;
4121
4122 Py_BEGIN_ALLOW_THREADS
4123 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4124 Py_END_ALLOW_THREADS
4125
4126 return value;
4127}
4128
4129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004130posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004131{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004132 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004133 return NULL;
4134
4135 /* Currently Only Uptime is Provided -- Others Later */
4136 return Py_BuildValue("ddddd",
4137 (double)0 /* t.tms_utime / HZ */,
4138 (double)0 /* t.tms_stime / HZ */,
4139 (double)0 /* t.tms_cutime / HZ */,
4140 (double)0 /* t.tms_cstime / HZ */,
4141 (double)system_uptime() / 1000);
4142}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004143#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004145posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004146{
4147 struct tms t;
4148 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004149 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004150 return NULL;
4151 errno = 0;
4152 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004153 if (c == (clock_t) -1)
4154 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004155 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004156 (double)t.tms_utime / HZ,
4157 (double)t.tms_stime / HZ,
4158 (double)t.tms_cutime / HZ,
4159 (double)t.tms_cstime / HZ,
4160 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004161}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004162#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004163#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004164
4165
Guido van Rossum87755a21996-09-07 00:59:43 +00004166#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004167#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004169posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004170{
4171 FILETIME create, exit, kernel, user;
4172 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004173 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004174 return NULL;
4175 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004176 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4177 /* The fields of a FILETIME structure are the hi and lo part
4178 of a 64-bit value expressed in 100 nanosecond units.
4179 1e7 is one second in such units; 1e-7 the inverse.
4180 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4181 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004182 return Py_BuildValue(
4183 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004184 (double)(kernel.dwHighDateTime*429.4967296 +
4185 kernel.dwLowDateTime*1e-7),
4186 (double)(user.dwHighDateTime*429.4967296 +
4187 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004188 (double)0,
4189 (double)0,
4190 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004191}
Guido van Rossum8d665e61996-06-26 18:22:49 +00004192#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004193
4194#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00004195static char posix_times__doc__[] =
4196"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
4197Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004198#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004199
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004200
Guido van Rossumb6775db1994-08-01 11:34:53 +00004201#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004202static char posix_setsid__doc__[] =
4203"setsid() -> None\n\
4204Call the system call setsid().";
4205
Barry Warsaw53699e91996-12-10 23:23:01 +00004206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004207posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004208{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004209 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004210 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004211 if (setsid() < 0)
4212 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004213 Py_INCREF(Py_None);
4214 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004215}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004216#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004217
Guido van Rossumb6775db1994-08-01 11:34:53 +00004218#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004219static char posix_setpgid__doc__[] =
4220"setpgid(pid, pgrp) -> None\n\
4221Call the system call setpgid().";
4222
Barry Warsaw53699e91996-12-10 23:23:01 +00004223static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004224posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004225{
4226 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004227 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004228 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004229 if (setpgid(pid, pgrp) < 0)
4230 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004231 Py_INCREF(Py_None);
4232 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004233}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004234#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004236
Guido van Rossumb6775db1994-08-01 11:34:53 +00004237#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004238static char posix_tcgetpgrp__doc__[] =
4239"tcgetpgrp(fd) -> pgid\n\
4240Return the process group associated with the terminal given by a fd.";
4241
Barry Warsaw53699e91996-12-10 23:23:01 +00004242static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004243posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004244{
4245 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004246 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004247 return NULL;
4248 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004249 if (pgid < 0)
4250 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004251 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004252}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004253#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004254
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004255
Guido van Rossumb6775db1994-08-01 11:34:53 +00004256#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004257static char posix_tcsetpgrp__doc__[] =
4258"tcsetpgrp(fd, pgid) -> None\n\
4259Set the process group associated with the terminal given by a fd.";
4260
Barry Warsaw53699e91996-12-10 23:23:01 +00004261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004262posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004263{
4264 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004265 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004266 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004267 if (tcsetpgrp(fd, pgid) < 0)
4268 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004269 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004270 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004271}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004272#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004273
Guido van Rossum687dd131993-05-17 08:34:16 +00004274/* Functions acting on file descriptors */
4275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004276static char posix_open__doc__[] =
4277"open(filename, flag [, mode=0777]) -> fd\n\
4278Open a file (for low level IO).";
4279
Barry Warsaw53699e91996-12-10 23:23:01 +00004280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004281posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004282{
Mark Hammondef8b6542001-05-13 08:04:26 +00004283 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004284 int flag;
4285 int mode = 0777;
4286 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004287 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004288 Py_FileSystemDefaultEncoding, &file,
4289 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004290 return NULL;
4291
Barry Warsaw53699e91996-12-10 23:23:01 +00004292 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004293 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004294 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004295 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004296 return posix_error_with_allocated_filename(file);
4297 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004298 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004299}
4300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004301
4302static char posix_close__doc__[] =
4303"close(fd) -> None\n\
4304Close a file descriptor (for low level IO).";
4305
Barry Warsaw53699e91996-12-10 23:23:01 +00004306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004307posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004308{
4309 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004310 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004311 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004312 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004313 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004314 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004315 if (res < 0)
4316 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004317 Py_INCREF(Py_None);
4318 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004319}
4320
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004321
4322static char posix_dup__doc__[] =
4323"dup(fd) -> fd2\n\
4324Return a duplicate of a file descriptor.";
4325
Barry Warsaw53699e91996-12-10 23:23:01 +00004326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004327posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004328{
4329 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004330 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004331 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004332 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004333 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004334 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004335 if (fd < 0)
4336 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004337 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004338}
4339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004340
4341static char posix_dup2__doc__[] =
4342"dup2(fd, fd2) -> None\n\
4343Duplicate file descriptor.";
4344
Barry Warsaw53699e91996-12-10 23:23:01 +00004345static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004346posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004347{
4348 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004349 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004350 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004351 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004352 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004353 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004354 if (res < 0)
4355 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004356 Py_INCREF(Py_None);
4357 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004358}
4359
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004360
4361static char posix_lseek__doc__[] =
4362"lseek(fd, pos, how) -> newpos\n\
4363Set the current position of a file descriptor.";
4364
Barry Warsaw53699e91996-12-10 23:23:01 +00004365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004366posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004367{
4368 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00004369#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004370 LONG_LONG pos, res;
4371#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004372 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004373#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004374 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004375 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004376 return NULL;
4377#ifdef SEEK_SET
4378 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4379 switch (how) {
4380 case 0: how = SEEK_SET; break;
4381 case 1: how = SEEK_CUR; break;
4382 case 2: how = SEEK_END; break;
4383 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004384#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004385
4386#if !defined(HAVE_LARGEFILE_SUPPORT)
4387 pos = PyInt_AsLong(posobj);
4388#else
4389 pos = PyLong_Check(posobj) ?
4390 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4391#endif
4392 if (PyErr_Occurred())
4393 return NULL;
4394
Barry Warsaw53699e91996-12-10 23:23:01 +00004395 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00004396#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004397 res = _lseeki64(fd, pos, how);
4398#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004399 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004400#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004401 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004402 if (res < 0)
4403 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004404
4405#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004406 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004407#else
4408 return PyLong_FromLongLong(res);
4409#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004410}
4411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004412
4413static char posix_read__doc__[] =
4414"read(fd, buffersize) -> string\n\
4415Read a file descriptor.";
4416
Barry Warsaw53699e91996-12-10 23:23:01 +00004417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004418posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004419{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004420 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004421 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004422 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004423 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004424 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004425 if (buffer == NULL)
4426 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004427 Py_BEGIN_ALLOW_THREADS
4428 n = read(fd, PyString_AsString(buffer), size);
4429 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004430 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004431 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004432 return posix_error();
4433 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004434 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004435 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004436 return buffer;
4437}
4438
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004439
4440static char posix_write__doc__[] =
4441"write(fd, string) -> byteswritten\n\
4442Write a string to a file descriptor.";
4443
Barry Warsaw53699e91996-12-10 23:23:01 +00004444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004445posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004446{
4447 int fd, size;
4448 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004449 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004450 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004451 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004452 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004453 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004454 if (size < 0)
4455 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004456 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004457}
4458
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004459
4460static char posix_fstat__doc__[]=
4461"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
4462Like stat(), but for an open file descriptor.";
4463
Barry Warsaw53699e91996-12-10 23:23:01 +00004464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004465posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004466{
4467 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004468 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004469 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004470 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004471 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004472 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004473 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004474 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004475 if (res != 0)
4476 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004477
Fred Drake699f3522000-06-29 21:12:41 +00004478 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004479}
4480
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004481
4482static char posix_fdopen__doc__[] =
4483"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
4484Return an open file object connected to a file descriptor.";
4485
Barry Warsaw53699e91996-12-10 23:23:01 +00004486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004487posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004488{
Guido van Rossum687dd131993-05-17 08:34:16 +00004489 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004490 char *mode = "r";
4491 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004492 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004493 PyObject *f;
4494 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004495 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004496
Barry Warsaw53699e91996-12-10 23:23:01 +00004497 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004498 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004499 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004500 if (fp == NULL)
4501 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004502 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004503 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004504 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004505 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004506}
4507
Skip Montanaro1517d842000-07-19 14:34:14 +00004508static char posix_isatty__doc__[] =
4509"isatty(fd) -> Boolean\n\
4510Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00004511connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00004512
4513static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004514posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004515{
4516 int fd;
4517 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4518 return NULL;
4519 return Py_BuildValue("i", isatty(fd));
4520}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004521
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004522#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004523static char posix_pipe__doc__[] =
4524"pipe() -> (read_end, write_end)\n\
4525Create a pipe.";
4526
Barry Warsaw53699e91996-12-10 23:23:01 +00004527static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004528posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004529{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004530#if defined(PYOS_OS2)
4531 HFILE read, write;
4532 APIRET rc;
4533
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004534 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004535 return NULL;
4536
4537 Py_BEGIN_ALLOW_THREADS
4538 rc = DosCreatePipe( &read, &write, 4096);
4539 Py_END_ALLOW_THREADS
4540 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004541 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004542
4543 return Py_BuildValue("(ii)", read, write);
4544#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00004545#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00004546 int fds[2];
4547 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004548 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004549 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004550 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004551 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004552 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004553 if (res != 0)
4554 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004555 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004556#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00004557 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004558 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004559 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004560 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004561 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004562 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004563 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004564 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004565 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004566 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004567 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4568 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004569 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004570#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004571#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004572}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004573#endif /* HAVE_PIPE */
4574
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004575
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004576#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004577static char posix_mkfifo__doc__[] =
4578"mkfifo(file, [, mode=0666]) -> None\n\
4579Create a FIFO (a POSIX named pipe).";
4580
Barry Warsaw53699e91996-12-10 23:23:01 +00004581static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004582posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004583{
4584 char *file;
4585 int mode = 0666;
4586 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004587 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004588 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004589 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004590 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004591 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004592 if (res < 0)
4593 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004594 Py_INCREF(Py_None);
4595 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004596}
4597#endif
4598
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004599
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004600#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004601static char posix_ftruncate__doc__[] =
4602"ftruncate(fd, length) -> None\n\
4603Truncate a file to a specified length.";
4604
Barry Warsaw53699e91996-12-10 23:23:01 +00004605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004606posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004607{
4608 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004609 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004610 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004611 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004612
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004613 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004614 return NULL;
4615
4616#if !defined(HAVE_LARGEFILE_SUPPORT)
4617 length = PyInt_AsLong(lenobj);
4618#else
4619 length = PyLong_Check(lenobj) ?
4620 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4621#endif
4622 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004623 return NULL;
4624
Barry Warsaw53699e91996-12-10 23:23:01 +00004625 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004626 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004627 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004628 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004629 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004630 return NULL;
4631 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004632 Py_INCREF(Py_None);
4633 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004634}
4635#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004636
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004637#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004638static char posix_putenv__doc__[] =
4639"putenv(key, value) -> None\n\
4640Change or add an environment variable.";
4641
Fred Drake762e2061999-08-26 17:23:54 +00004642/* Save putenv() parameters as values here, so we can collect them when they
4643 * get re-set with another call for the same key. */
4644static PyObject *posix_putenv_garbage;
4645
Tim Peters5aa91602002-01-30 05:46:57 +00004646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004647posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004648{
4649 char *s1, *s2;
4650 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004651 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004652 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004653
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004654 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004655 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004656
4657#if defined(PYOS_OS2)
4658 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4659 APIRET rc;
4660
4661 if (strlen(s2) == 0) /* If New Value is an Empty String */
4662 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4663
4664 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4665 if (rc != NO_ERROR)
4666 return os2_error(rc);
4667
4668 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4669 APIRET rc;
4670
4671 if (strlen(s2) == 0) /* If New Value is an Empty String */
4672 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4673
4674 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4675 if (rc != NO_ERROR)
4676 return os2_error(rc);
4677 } else {
4678#endif
4679
Fred Drake762e2061999-08-26 17:23:54 +00004680 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004681 len = strlen(s1) + strlen(s2) + 2;
4682 /* len includes space for a trailing \0; the size arg to
4683 PyString_FromStringAndSize does not count that */
4684 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004685 if (newstr == NULL)
4686 return PyErr_NoMemory();
4687 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004688 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004689 if (putenv(new)) {
4690 posix_error();
4691 return NULL;
4692 }
Fred Drake762e2061999-08-26 17:23:54 +00004693 /* Install the first arg and newstr in posix_putenv_garbage;
4694 * this will cause previous value to be collected. This has to
4695 * happen after the real putenv() call because the old value
4696 * was still accessible until then. */
4697 if (PyDict_SetItem(posix_putenv_garbage,
4698 PyTuple_GET_ITEM(args, 0), newstr)) {
4699 /* really not much we can do; just leak */
4700 PyErr_Clear();
4701 }
4702 else {
4703 Py_DECREF(newstr);
4704 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004705
4706#if defined(PYOS_OS2)
4707 }
4708#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004709 Py_INCREF(Py_None);
4710 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004711}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004712#endif /* putenv */
4713
Guido van Rossumc524d952001-10-19 01:31:59 +00004714#ifdef HAVE_UNSETENV
4715static char posix_unsetenv__doc__[] =
4716"unsetenv(key) -> None\n\
4717Delete an environment variable.";
4718
4719static PyObject *
4720posix_unsetenv(PyObject *self, PyObject *args)
4721{
4722 char *s1;
4723
4724 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4725 return NULL;
4726
4727 unsetenv(s1);
4728
4729 /* Remove the key from posix_putenv_garbage;
4730 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004731 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004732 * old value was still accessible until then.
4733 */
4734 if (PyDict_DelItem(posix_putenv_garbage,
4735 PyTuple_GET_ITEM(args, 0))) {
4736 /* really not much we can do; just leak */
4737 PyErr_Clear();
4738 }
4739
4740 Py_INCREF(Py_None);
4741 return Py_None;
4742}
4743#endif /* unsetenv */
4744
Guido van Rossumb6a47161997-09-15 22:54:34 +00004745#ifdef HAVE_STRERROR
4746static char posix_strerror__doc__[] =
4747"strerror(code) -> string\n\
4748Translate an error code to a message string.";
4749
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004751posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004752{
4753 int code;
4754 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004755 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004756 return NULL;
4757 message = strerror(code);
4758 if (message == NULL) {
4759 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004760 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004761 return NULL;
4762 }
4763 return PyString_FromString(message);
4764}
4765#endif /* strerror */
4766
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004767
Guido van Rossumc9641791998-08-04 15:26:23 +00004768#ifdef HAVE_SYS_WAIT_H
4769
4770#ifdef WIFSTOPPED
4771static char posix_WIFSTOPPED__doc__[] =
4772"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004773Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004774
4775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004776posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004777{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004778#ifdef UNION_WAIT
4779 union wait status;
4780#define status_i (status.w_status)
4781#else
4782 int status;
4783#define status_i status
4784#endif
4785 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004786
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004787 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004788 {
4789 return NULL;
4790 }
Tim Peters5aa91602002-01-30 05:46:57 +00004791
Guido van Rossumc9641791998-08-04 15:26:23 +00004792 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004793#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004794}
4795#endif /* WIFSTOPPED */
4796
4797#ifdef WIFSIGNALED
4798static char posix_WIFSIGNALED__doc__[] =
4799"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004800Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004801
4802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004803posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004804{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004805#ifdef UNION_WAIT
4806 union wait status;
4807#define status_i (status.w_status)
4808#else
4809 int status;
4810#define status_i status
4811#endif
4812 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004813
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004814 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004815 {
4816 return NULL;
4817 }
Tim Peters5aa91602002-01-30 05:46:57 +00004818
Guido van Rossumc9641791998-08-04 15:26:23 +00004819 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004820#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004821}
4822#endif /* WIFSIGNALED */
4823
4824#ifdef WIFEXITED
4825static char posix_WIFEXITED__doc__[] =
4826"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004827Return true if the process returning 'status' exited using the exit()\n\
4828system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004829
4830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004831posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004832{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004833#ifdef UNION_WAIT
4834 union wait status;
4835#define status_i (status.w_status)
4836#else
4837 int status;
4838#define status_i status
4839#endif
4840 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004841
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004842 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004843 {
4844 return NULL;
4845 }
Tim Peters5aa91602002-01-30 05:46:57 +00004846
Guido van Rossumc9641791998-08-04 15:26:23 +00004847 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004848#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004849}
4850#endif /* WIFEXITED */
4851
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004852#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004853static char posix_WEXITSTATUS__doc__[] =
4854"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004855Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004856
4857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004858posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004859{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004860#ifdef UNION_WAIT
4861 union wait status;
4862#define status_i (status.w_status)
4863#else
4864 int status;
4865#define status_i status
4866#endif
4867 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004868
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004869 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004870 {
4871 return NULL;
4872 }
Tim Peters5aa91602002-01-30 05:46:57 +00004873
Guido van Rossumc9641791998-08-04 15:26:23 +00004874 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004875#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004876}
4877#endif /* WEXITSTATUS */
4878
4879#ifdef WTERMSIG
4880static char posix_WTERMSIG__doc__[] =
4881"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004882Return the signal that terminated the process that provided the 'status'\n\
4883value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004884
4885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004886posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004887{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004888#ifdef UNION_WAIT
4889 union wait status;
4890#define status_i (status.w_status)
4891#else
4892 int status;
4893#define status_i status
4894#endif
4895 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004896
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004897 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004898 {
4899 return NULL;
4900 }
Tim Peters5aa91602002-01-30 05:46:57 +00004901
Guido van Rossumc9641791998-08-04 15:26:23 +00004902 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004903#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004904}
4905#endif /* WTERMSIG */
4906
4907#ifdef WSTOPSIG
4908static char posix_WSTOPSIG__doc__[] =
4909"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004910Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004911
4912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004913posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004914{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004915#ifdef UNION_WAIT
4916 union wait status;
4917#define status_i (status.w_status)
4918#else
4919 int status;
4920#define status_i status
4921#endif
4922 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004923
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004924 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004925 {
4926 return NULL;
4927 }
Tim Peters5aa91602002-01-30 05:46:57 +00004928
Guido van Rossumc9641791998-08-04 15:26:23 +00004929 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004930#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004931}
4932#endif /* WSTOPSIG */
4933
4934#endif /* HAVE_SYS_WAIT_H */
4935
4936
Guido van Rossum94f6f721999-01-06 18:42:14 +00004937#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004938#ifdef _SCO_DS
4939/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4940 needed definitions in sys/statvfs.h */
4941#define _SVID3
4942#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004943#include <sys/statvfs.h>
4944
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004945static PyObject*
4946_pystatvfs_fromstructstatvfs(struct statvfs st) {
4947 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4948 if (v == NULL)
4949 return NULL;
4950
4951#if !defined(HAVE_LARGEFILE_SUPPORT)
4952 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4953 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4954 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4955 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4956 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4957 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4958 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4959 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4960 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4961 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4962#else
4963 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4964 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00004965 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004966 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00004967 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004968 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4969 PyStructSequence_SET_ITEM(v, 4,
4970 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00004971 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004972 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00004973 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004974 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00004975 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004976 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4977 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4978 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4979#endif
4980
4981 return v;
4982}
4983
Guido van Rossum94f6f721999-01-06 18:42:14 +00004984static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004985"fstatvfs(fd) -> \n\
4986 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004987Perform an fstatvfs system call on the given fd.";
4988
4989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004990posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004991{
4992 int fd, res;
4993 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004994
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004995 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004996 return NULL;
4997 Py_BEGIN_ALLOW_THREADS
4998 res = fstatvfs(fd, &st);
4999 Py_END_ALLOW_THREADS
5000 if (res != 0)
5001 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005002
5003 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005004}
5005#endif /* HAVE_FSTATVFS */
5006
5007
5008#if defined(HAVE_STATVFS)
5009#include <sys/statvfs.h>
5010
5011static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005012"statvfs(path) -> \n\
5013 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005014Perform a statvfs system call on the given path.";
5015
5016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005017posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005018{
5019 char *path;
5020 int res;
5021 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005022 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005023 return NULL;
5024 Py_BEGIN_ALLOW_THREADS
5025 res = statvfs(path, &st);
5026 Py_END_ALLOW_THREADS
5027 if (res != 0)
5028 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005029
5030 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005031}
5032#endif /* HAVE_STATVFS */
5033
5034
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005035#ifdef HAVE_TEMPNAM
5036static char posix_tempnam__doc__[] = "\
5037tempnam([dir[, prefix]]) -> string\n\
5038Return a unique name for a temporary file.\n\
5039The directory and a short may be specified as strings; they may be omitted\n\
5040or None if not needed.";
5041
5042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005043posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005044{
5045 PyObject *result = NULL;
5046 char *dir = NULL;
5047 char *pfx = NULL;
5048 char *name;
5049
5050 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5051 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005052
5053 if (PyErr_Warn(PyExc_RuntimeWarning,
5054 "tempnam is a potential security risk to your program") < 0)
5055 return NULL;
5056
Fred Drake78b71c22001-07-17 20:37:36 +00005057#ifdef MS_WIN32
5058 name = _tempnam(dir, pfx);
5059#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005060 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005061#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005062 if (name == NULL)
5063 return PyErr_NoMemory();
5064 result = PyString_FromString(name);
5065 free(name);
5066 return result;
5067}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005068#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005069
5070
5071#ifdef HAVE_TMPFILE
5072static char posix_tmpfile__doc__[] = "\
5073tmpfile() -> file object\n\
5074Create a temporary file with no directory entries.";
5075
5076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005077posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005078{
5079 FILE *fp;
5080
5081 if (!PyArg_ParseTuple(args, ":tmpfile"))
5082 return NULL;
5083 fp = tmpfile();
5084 if (fp == NULL)
5085 return posix_error();
5086 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
5087}
5088#endif
5089
5090
5091#ifdef HAVE_TMPNAM
5092static char posix_tmpnam__doc__[] = "\
5093tmpnam() -> string\n\
5094Return a unique name for a temporary file.";
5095
5096static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005097posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005098{
5099 char buffer[L_tmpnam];
5100 char *name;
5101
5102 if (!PyArg_ParseTuple(args, ":tmpnam"))
5103 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005104
5105 if (PyErr_Warn(PyExc_RuntimeWarning,
5106 "tmpnam is a potential security risk to your program") < 0)
5107 return NULL;
5108
Greg Wardb48bc172000-03-01 21:51:56 +00005109#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005110 name = tmpnam_r(buffer);
5111#else
5112 name = tmpnam(buffer);
5113#endif
5114 if (name == NULL) {
5115 PyErr_SetObject(PyExc_OSError,
5116 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005117#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005118 "unexpected NULL from tmpnam_r"
5119#else
5120 "unexpected NULL from tmpnam"
5121#endif
5122 ));
5123 return NULL;
5124 }
5125 return PyString_FromString(buffer);
5126}
5127#endif
5128
5129
Fred Drakec9680921999-12-13 16:37:25 +00005130/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5131 * It maps strings representing configuration variable names to
5132 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005133 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005134 * rarely-used constants. There are three separate tables that use
5135 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005136 *
5137 * This code is always included, even if none of the interfaces that
5138 * need it are included. The #if hackery needed to avoid it would be
5139 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005140 */
5141struct constdef {
5142 char *name;
5143 long value;
5144};
5145
Fred Drake12c6e2d1999-12-14 21:25:03 +00005146static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005147conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5148 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005149{
5150 if (PyInt_Check(arg)) {
5151 *valuep = PyInt_AS_LONG(arg);
5152 return 1;
5153 }
5154 if (PyString_Check(arg)) {
5155 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005156 size_t lo = 0;
5157 size_t mid;
5158 size_t hi = tablesize;
5159 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005160 char *confname = PyString_AS_STRING(arg);
5161 while (lo < hi) {
5162 mid = (lo + hi) / 2;
5163 cmp = strcmp(confname, table[mid].name);
5164 if (cmp < 0)
5165 hi = mid;
5166 else if (cmp > 0)
5167 lo = mid + 1;
5168 else {
5169 *valuep = table[mid].value;
5170 return 1;
5171 }
5172 }
5173 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5174 }
5175 else
5176 PyErr_SetString(PyExc_TypeError,
5177 "configuration names must be strings or integers");
5178 return 0;
5179}
5180
5181
5182#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5183static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005184#ifdef _PC_ABI_AIO_XFER_MAX
5185 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5186#endif
5187#ifdef _PC_ABI_ASYNC_IO
5188 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5189#endif
Fred Drakec9680921999-12-13 16:37:25 +00005190#ifdef _PC_ASYNC_IO
5191 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5192#endif
5193#ifdef _PC_CHOWN_RESTRICTED
5194 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5195#endif
5196#ifdef _PC_FILESIZEBITS
5197 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5198#endif
5199#ifdef _PC_LAST
5200 {"PC_LAST", _PC_LAST},
5201#endif
5202#ifdef _PC_LINK_MAX
5203 {"PC_LINK_MAX", _PC_LINK_MAX},
5204#endif
5205#ifdef _PC_MAX_CANON
5206 {"PC_MAX_CANON", _PC_MAX_CANON},
5207#endif
5208#ifdef _PC_MAX_INPUT
5209 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5210#endif
5211#ifdef _PC_NAME_MAX
5212 {"PC_NAME_MAX", _PC_NAME_MAX},
5213#endif
5214#ifdef _PC_NO_TRUNC
5215 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5216#endif
5217#ifdef _PC_PATH_MAX
5218 {"PC_PATH_MAX", _PC_PATH_MAX},
5219#endif
5220#ifdef _PC_PIPE_BUF
5221 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5222#endif
5223#ifdef _PC_PRIO_IO
5224 {"PC_PRIO_IO", _PC_PRIO_IO},
5225#endif
5226#ifdef _PC_SOCK_MAXBUF
5227 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5228#endif
5229#ifdef _PC_SYNC_IO
5230 {"PC_SYNC_IO", _PC_SYNC_IO},
5231#endif
5232#ifdef _PC_VDISABLE
5233 {"PC_VDISABLE", _PC_VDISABLE},
5234#endif
5235};
5236
Fred Drakec9680921999-12-13 16:37:25 +00005237static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005238conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005239{
5240 return conv_confname(arg, valuep, posix_constants_pathconf,
5241 sizeof(posix_constants_pathconf)
5242 / sizeof(struct constdef));
5243}
5244#endif
5245
5246#ifdef HAVE_FPATHCONF
5247static char posix_fpathconf__doc__[] = "\
5248fpathconf(fd, name) -> integer\n\
5249Return the configuration limit name for the file descriptor fd.\n\
5250If there is no limit, return -1.";
5251
5252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005253posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005254{
5255 PyObject *result = NULL;
5256 int name, fd;
5257
Fred Drake12c6e2d1999-12-14 21:25:03 +00005258 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5259 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005260 long limit;
5261
5262 errno = 0;
5263 limit = fpathconf(fd, name);
5264 if (limit == -1 && errno != 0)
5265 posix_error();
5266 else
5267 result = PyInt_FromLong(limit);
5268 }
5269 return result;
5270}
5271#endif
5272
5273
5274#ifdef HAVE_PATHCONF
5275static char posix_pathconf__doc__[] = "\
5276pathconf(path, name) -> integer\n\
5277Return the configuration limit name for the file or directory path.\n\
5278If there is no limit, return -1.";
5279
5280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005281posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005282{
5283 PyObject *result = NULL;
5284 int name;
5285 char *path;
5286
5287 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5288 conv_path_confname, &name)) {
5289 long limit;
5290
5291 errno = 0;
5292 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005293 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005294 if (errno == EINVAL)
5295 /* could be a path or name problem */
5296 posix_error();
5297 else
5298 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005299 }
Fred Drakec9680921999-12-13 16:37:25 +00005300 else
5301 result = PyInt_FromLong(limit);
5302 }
5303 return result;
5304}
5305#endif
5306
5307#ifdef HAVE_CONFSTR
5308static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005309#ifdef _CS_ARCHITECTURE
5310 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5311#endif
5312#ifdef _CS_HOSTNAME
5313 {"CS_HOSTNAME", _CS_HOSTNAME},
5314#endif
5315#ifdef _CS_HW_PROVIDER
5316 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5317#endif
5318#ifdef _CS_HW_SERIAL
5319 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5320#endif
5321#ifdef _CS_INITTAB_NAME
5322 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5323#endif
Fred Drakec9680921999-12-13 16:37:25 +00005324#ifdef _CS_LFS64_CFLAGS
5325 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5326#endif
5327#ifdef _CS_LFS64_LDFLAGS
5328 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5329#endif
5330#ifdef _CS_LFS64_LIBS
5331 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5332#endif
5333#ifdef _CS_LFS64_LINTFLAGS
5334 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5335#endif
5336#ifdef _CS_LFS_CFLAGS
5337 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5338#endif
5339#ifdef _CS_LFS_LDFLAGS
5340 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5341#endif
5342#ifdef _CS_LFS_LIBS
5343 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5344#endif
5345#ifdef _CS_LFS_LINTFLAGS
5346 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5347#endif
Fred Draked86ed291999-12-15 15:34:33 +00005348#ifdef _CS_MACHINE
5349 {"CS_MACHINE", _CS_MACHINE},
5350#endif
Fred Drakec9680921999-12-13 16:37:25 +00005351#ifdef _CS_PATH
5352 {"CS_PATH", _CS_PATH},
5353#endif
Fred Draked86ed291999-12-15 15:34:33 +00005354#ifdef _CS_RELEASE
5355 {"CS_RELEASE", _CS_RELEASE},
5356#endif
5357#ifdef _CS_SRPC_DOMAIN
5358 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5359#endif
5360#ifdef _CS_SYSNAME
5361 {"CS_SYSNAME", _CS_SYSNAME},
5362#endif
5363#ifdef _CS_VERSION
5364 {"CS_VERSION", _CS_VERSION},
5365#endif
Fred Drakec9680921999-12-13 16:37:25 +00005366#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5367 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5368#endif
5369#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5370 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5371#endif
5372#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5373 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5374#endif
5375#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5376 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5377#endif
5378#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5379 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5380#endif
5381#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5382 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5383#endif
5384#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5385 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5386#endif
5387#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5388 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5389#endif
5390#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5391 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5392#endif
5393#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5394 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5395#endif
5396#ifdef _CS_XBS5_LP64_OFF64_LIBS
5397 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5398#endif
5399#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5400 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5401#endif
5402#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5403 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5404#endif
5405#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5406 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5407#endif
5408#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5409 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5410#endif
5411#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5412 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5413#endif
Fred Draked86ed291999-12-15 15:34:33 +00005414#ifdef _MIPS_CS_AVAIL_PROCESSORS
5415 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5416#endif
5417#ifdef _MIPS_CS_BASE
5418 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5419#endif
5420#ifdef _MIPS_CS_HOSTID
5421 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5422#endif
5423#ifdef _MIPS_CS_HW_NAME
5424 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5425#endif
5426#ifdef _MIPS_CS_NUM_PROCESSORS
5427 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5428#endif
5429#ifdef _MIPS_CS_OSREL_MAJ
5430 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5431#endif
5432#ifdef _MIPS_CS_OSREL_MIN
5433 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5434#endif
5435#ifdef _MIPS_CS_OSREL_PATCH
5436 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5437#endif
5438#ifdef _MIPS_CS_OS_NAME
5439 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5440#endif
5441#ifdef _MIPS_CS_OS_PROVIDER
5442 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5443#endif
5444#ifdef _MIPS_CS_PROCESSORS
5445 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5446#endif
5447#ifdef _MIPS_CS_SERIAL
5448 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5449#endif
5450#ifdef _MIPS_CS_VENDOR
5451 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5452#endif
Fred Drakec9680921999-12-13 16:37:25 +00005453};
5454
5455static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005456conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005457{
5458 return conv_confname(arg, valuep, posix_constants_confstr,
5459 sizeof(posix_constants_confstr)
5460 / sizeof(struct constdef));
5461}
5462
5463static char posix_confstr__doc__[] = "\
5464confstr(name) -> string\n\
5465Return a string-valued system configuration variable.";
5466
5467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005468posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005469{
5470 PyObject *result = NULL;
5471 int name;
5472 char buffer[64];
5473
5474 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5475 int len = confstr(name, buffer, sizeof(buffer));
5476
Fred Drakec9680921999-12-13 16:37:25 +00005477 errno = 0;
5478 if (len == 0) {
5479 if (errno != 0)
5480 posix_error();
5481 else
5482 result = PyString_FromString("");
5483 }
5484 else {
5485 if (len >= sizeof(buffer)) {
5486 result = PyString_FromStringAndSize(NULL, len);
5487 if (result != NULL)
5488 confstr(name, PyString_AS_STRING(result), len+1);
5489 }
5490 else
5491 result = PyString_FromString(buffer);
5492 }
5493 }
5494 return result;
5495}
5496#endif
5497
5498
5499#ifdef HAVE_SYSCONF
5500static struct constdef posix_constants_sysconf[] = {
5501#ifdef _SC_2_CHAR_TERM
5502 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5503#endif
5504#ifdef _SC_2_C_BIND
5505 {"SC_2_C_BIND", _SC_2_C_BIND},
5506#endif
5507#ifdef _SC_2_C_DEV
5508 {"SC_2_C_DEV", _SC_2_C_DEV},
5509#endif
5510#ifdef _SC_2_C_VERSION
5511 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5512#endif
5513#ifdef _SC_2_FORT_DEV
5514 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5515#endif
5516#ifdef _SC_2_FORT_RUN
5517 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5518#endif
5519#ifdef _SC_2_LOCALEDEF
5520 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5521#endif
5522#ifdef _SC_2_SW_DEV
5523 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5524#endif
5525#ifdef _SC_2_UPE
5526 {"SC_2_UPE", _SC_2_UPE},
5527#endif
5528#ifdef _SC_2_VERSION
5529 {"SC_2_VERSION", _SC_2_VERSION},
5530#endif
Fred Draked86ed291999-12-15 15:34:33 +00005531#ifdef _SC_ABI_ASYNCHRONOUS_IO
5532 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5533#endif
5534#ifdef _SC_ACL
5535 {"SC_ACL", _SC_ACL},
5536#endif
Fred Drakec9680921999-12-13 16:37:25 +00005537#ifdef _SC_AIO_LISTIO_MAX
5538 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5539#endif
Fred Drakec9680921999-12-13 16:37:25 +00005540#ifdef _SC_AIO_MAX
5541 {"SC_AIO_MAX", _SC_AIO_MAX},
5542#endif
5543#ifdef _SC_AIO_PRIO_DELTA_MAX
5544 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5545#endif
5546#ifdef _SC_ARG_MAX
5547 {"SC_ARG_MAX", _SC_ARG_MAX},
5548#endif
5549#ifdef _SC_ASYNCHRONOUS_IO
5550 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5551#endif
5552#ifdef _SC_ATEXIT_MAX
5553 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5554#endif
Fred Draked86ed291999-12-15 15:34:33 +00005555#ifdef _SC_AUDIT
5556 {"SC_AUDIT", _SC_AUDIT},
5557#endif
Fred Drakec9680921999-12-13 16:37:25 +00005558#ifdef _SC_AVPHYS_PAGES
5559 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5560#endif
5561#ifdef _SC_BC_BASE_MAX
5562 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5563#endif
5564#ifdef _SC_BC_DIM_MAX
5565 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5566#endif
5567#ifdef _SC_BC_SCALE_MAX
5568 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5569#endif
5570#ifdef _SC_BC_STRING_MAX
5571 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5572#endif
Fred Draked86ed291999-12-15 15:34:33 +00005573#ifdef _SC_CAP
5574 {"SC_CAP", _SC_CAP},
5575#endif
Fred Drakec9680921999-12-13 16:37:25 +00005576#ifdef _SC_CHARCLASS_NAME_MAX
5577 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5578#endif
5579#ifdef _SC_CHAR_BIT
5580 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5581#endif
5582#ifdef _SC_CHAR_MAX
5583 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5584#endif
5585#ifdef _SC_CHAR_MIN
5586 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5587#endif
5588#ifdef _SC_CHILD_MAX
5589 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5590#endif
5591#ifdef _SC_CLK_TCK
5592 {"SC_CLK_TCK", _SC_CLK_TCK},
5593#endif
5594#ifdef _SC_COHER_BLKSZ
5595 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5596#endif
5597#ifdef _SC_COLL_WEIGHTS_MAX
5598 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5599#endif
5600#ifdef _SC_DCACHE_ASSOC
5601 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5602#endif
5603#ifdef _SC_DCACHE_BLKSZ
5604 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5605#endif
5606#ifdef _SC_DCACHE_LINESZ
5607 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5608#endif
5609#ifdef _SC_DCACHE_SZ
5610 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5611#endif
5612#ifdef _SC_DCACHE_TBLKSZ
5613 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5614#endif
5615#ifdef _SC_DELAYTIMER_MAX
5616 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5617#endif
5618#ifdef _SC_EQUIV_CLASS_MAX
5619 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5620#endif
5621#ifdef _SC_EXPR_NEST_MAX
5622 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5623#endif
5624#ifdef _SC_FSYNC
5625 {"SC_FSYNC", _SC_FSYNC},
5626#endif
5627#ifdef _SC_GETGR_R_SIZE_MAX
5628 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5629#endif
5630#ifdef _SC_GETPW_R_SIZE_MAX
5631 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5632#endif
5633#ifdef _SC_ICACHE_ASSOC
5634 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5635#endif
5636#ifdef _SC_ICACHE_BLKSZ
5637 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5638#endif
5639#ifdef _SC_ICACHE_LINESZ
5640 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5641#endif
5642#ifdef _SC_ICACHE_SZ
5643 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5644#endif
Fred Draked86ed291999-12-15 15:34:33 +00005645#ifdef _SC_INF
5646 {"SC_INF", _SC_INF},
5647#endif
Fred Drakec9680921999-12-13 16:37:25 +00005648#ifdef _SC_INT_MAX
5649 {"SC_INT_MAX", _SC_INT_MAX},
5650#endif
5651#ifdef _SC_INT_MIN
5652 {"SC_INT_MIN", _SC_INT_MIN},
5653#endif
5654#ifdef _SC_IOV_MAX
5655 {"SC_IOV_MAX", _SC_IOV_MAX},
5656#endif
Fred Draked86ed291999-12-15 15:34:33 +00005657#ifdef _SC_IP_SECOPTS
5658 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5659#endif
Fred Drakec9680921999-12-13 16:37:25 +00005660#ifdef _SC_JOB_CONTROL
5661 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5662#endif
Fred Draked86ed291999-12-15 15:34:33 +00005663#ifdef _SC_KERN_POINTERS
5664 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5665#endif
5666#ifdef _SC_KERN_SIM
5667 {"SC_KERN_SIM", _SC_KERN_SIM},
5668#endif
Fred Drakec9680921999-12-13 16:37:25 +00005669#ifdef _SC_LINE_MAX
5670 {"SC_LINE_MAX", _SC_LINE_MAX},
5671#endif
5672#ifdef _SC_LOGIN_NAME_MAX
5673 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5674#endif
5675#ifdef _SC_LOGNAME_MAX
5676 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5677#endif
5678#ifdef _SC_LONG_BIT
5679 {"SC_LONG_BIT", _SC_LONG_BIT},
5680#endif
Fred Draked86ed291999-12-15 15:34:33 +00005681#ifdef _SC_MAC
5682 {"SC_MAC", _SC_MAC},
5683#endif
Fred Drakec9680921999-12-13 16:37:25 +00005684#ifdef _SC_MAPPED_FILES
5685 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5686#endif
5687#ifdef _SC_MAXPID
5688 {"SC_MAXPID", _SC_MAXPID},
5689#endif
5690#ifdef _SC_MB_LEN_MAX
5691 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5692#endif
5693#ifdef _SC_MEMLOCK
5694 {"SC_MEMLOCK", _SC_MEMLOCK},
5695#endif
5696#ifdef _SC_MEMLOCK_RANGE
5697 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5698#endif
5699#ifdef _SC_MEMORY_PROTECTION
5700 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5701#endif
5702#ifdef _SC_MESSAGE_PASSING
5703 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5704#endif
Fred Draked86ed291999-12-15 15:34:33 +00005705#ifdef _SC_MMAP_FIXED_ALIGNMENT
5706 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5707#endif
Fred Drakec9680921999-12-13 16:37:25 +00005708#ifdef _SC_MQ_OPEN_MAX
5709 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5710#endif
5711#ifdef _SC_MQ_PRIO_MAX
5712 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5713#endif
Fred Draked86ed291999-12-15 15:34:33 +00005714#ifdef _SC_NACLS_MAX
5715 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5716#endif
Fred Drakec9680921999-12-13 16:37:25 +00005717#ifdef _SC_NGROUPS_MAX
5718 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5719#endif
5720#ifdef _SC_NL_ARGMAX
5721 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5722#endif
5723#ifdef _SC_NL_LANGMAX
5724 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5725#endif
5726#ifdef _SC_NL_MSGMAX
5727 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5728#endif
5729#ifdef _SC_NL_NMAX
5730 {"SC_NL_NMAX", _SC_NL_NMAX},
5731#endif
5732#ifdef _SC_NL_SETMAX
5733 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5734#endif
5735#ifdef _SC_NL_TEXTMAX
5736 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5737#endif
5738#ifdef _SC_NPROCESSORS_CONF
5739 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5740#endif
5741#ifdef _SC_NPROCESSORS_ONLN
5742 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5743#endif
Fred Draked86ed291999-12-15 15:34:33 +00005744#ifdef _SC_NPROC_CONF
5745 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5746#endif
5747#ifdef _SC_NPROC_ONLN
5748 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5749#endif
Fred Drakec9680921999-12-13 16:37:25 +00005750#ifdef _SC_NZERO
5751 {"SC_NZERO", _SC_NZERO},
5752#endif
5753#ifdef _SC_OPEN_MAX
5754 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5755#endif
5756#ifdef _SC_PAGESIZE
5757 {"SC_PAGESIZE", _SC_PAGESIZE},
5758#endif
5759#ifdef _SC_PAGE_SIZE
5760 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5761#endif
5762#ifdef _SC_PASS_MAX
5763 {"SC_PASS_MAX", _SC_PASS_MAX},
5764#endif
5765#ifdef _SC_PHYS_PAGES
5766 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5767#endif
5768#ifdef _SC_PII
5769 {"SC_PII", _SC_PII},
5770#endif
5771#ifdef _SC_PII_INTERNET
5772 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5773#endif
5774#ifdef _SC_PII_INTERNET_DGRAM
5775 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5776#endif
5777#ifdef _SC_PII_INTERNET_STREAM
5778 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5779#endif
5780#ifdef _SC_PII_OSI
5781 {"SC_PII_OSI", _SC_PII_OSI},
5782#endif
5783#ifdef _SC_PII_OSI_CLTS
5784 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5785#endif
5786#ifdef _SC_PII_OSI_COTS
5787 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5788#endif
5789#ifdef _SC_PII_OSI_M
5790 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5791#endif
5792#ifdef _SC_PII_SOCKET
5793 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5794#endif
5795#ifdef _SC_PII_XTI
5796 {"SC_PII_XTI", _SC_PII_XTI},
5797#endif
5798#ifdef _SC_POLL
5799 {"SC_POLL", _SC_POLL},
5800#endif
5801#ifdef _SC_PRIORITIZED_IO
5802 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5803#endif
5804#ifdef _SC_PRIORITY_SCHEDULING
5805 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5806#endif
5807#ifdef _SC_REALTIME_SIGNALS
5808 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5809#endif
5810#ifdef _SC_RE_DUP_MAX
5811 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5812#endif
5813#ifdef _SC_RTSIG_MAX
5814 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5815#endif
5816#ifdef _SC_SAVED_IDS
5817 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5818#endif
5819#ifdef _SC_SCHAR_MAX
5820 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5821#endif
5822#ifdef _SC_SCHAR_MIN
5823 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5824#endif
5825#ifdef _SC_SELECT
5826 {"SC_SELECT", _SC_SELECT},
5827#endif
5828#ifdef _SC_SEMAPHORES
5829 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5830#endif
5831#ifdef _SC_SEM_NSEMS_MAX
5832 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5833#endif
5834#ifdef _SC_SEM_VALUE_MAX
5835 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5836#endif
5837#ifdef _SC_SHARED_MEMORY_OBJECTS
5838 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5839#endif
5840#ifdef _SC_SHRT_MAX
5841 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5842#endif
5843#ifdef _SC_SHRT_MIN
5844 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5845#endif
5846#ifdef _SC_SIGQUEUE_MAX
5847 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5848#endif
5849#ifdef _SC_SIGRT_MAX
5850 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5851#endif
5852#ifdef _SC_SIGRT_MIN
5853 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5854#endif
Fred Draked86ed291999-12-15 15:34:33 +00005855#ifdef _SC_SOFTPOWER
5856 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5857#endif
Fred Drakec9680921999-12-13 16:37:25 +00005858#ifdef _SC_SPLIT_CACHE
5859 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5860#endif
5861#ifdef _SC_SSIZE_MAX
5862 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5863#endif
5864#ifdef _SC_STACK_PROT
5865 {"SC_STACK_PROT", _SC_STACK_PROT},
5866#endif
5867#ifdef _SC_STREAM_MAX
5868 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5869#endif
5870#ifdef _SC_SYNCHRONIZED_IO
5871 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5872#endif
5873#ifdef _SC_THREADS
5874 {"SC_THREADS", _SC_THREADS},
5875#endif
5876#ifdef _SC_THREAD_ATTR_STACKADDR
5877 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5878#endif
5879#ifdef _SC_THREAD_ATTR_STACKSIZE
5880 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5881#endif
5882#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5883 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5884#endif
5885#ifdef _SC_THREAD_KEYS_MAX
5886 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5887#endif
5888#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5889 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5890#endif
5891#ifdef _SC_THREAD_PRIO_INHERIT
5892 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5893#endif
5894#ifdef _SC_THREAD_PRIO_PROTECT
5895 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5896#endif
5897#ifdef _SC_THREAD_PROCESS_SHARED
5898 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5899#endif
5900#ifdef _SC_THREAD_SAFE_FUNCTIONS
5901 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5902#endif
5903#ifdef _SC_THREAD_STACK_MIN
5904 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5905#endif
5906#ifdef _SC_THREAD_THREADS_MAX
5907 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5908#endif
5909#ifdef _SC_TIMERS
5910 {"SC_TIMERS", _SC_TIMERS},
5911#endif
5912#ifdef _SC_TIMER_MAX
5913 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5914#endif
5915#ifdef _SC_TTY_NAME_MAX
5916 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5917#endif
5918#ifdef _SC_TZNAME_MAX
5919 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5920#endif
5921#ifdef _SC_T_IOV_MAX
5922 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5923#endif
5924#ifdef _SC_UCHAR_MAX
5925 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5926#endif
5927#ifdef _SC_UINT_MAX
5928 {"SC_UINT_MAX", _SC_UINT_MAX},
5929#endif
5930#ifdef _SC_UIO_MAXIOV
5931 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5932#endif
5933#ifdef _SC_ULONG_MAX
5934 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5935#endif
5936#ifdef _SC_USHRT_MAX
5937 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5938#endif
5939#ifdef _SC_VERSION
5940 {"SC_VERSION", _SC_VERSION},
5941#endif
5942#ifdef _SC_WORD_BIT
5943 {"SC_WORD_BIT", _SC_WORD_BIT},
5944#endif
5945#ifdef _SC_XBS5_ILP32_OFF32
5946 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5947#endif
5948#ifdef _SC_XBS5_ILP32_OFFBIG
5949 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5950#endif
5951#ifdef _SC_XBS5_LP64_OFF64
5952 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5953#endif
5954#ifdef _SC_XBS5_LPBIG_OFFBIG
5955 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5956#endif
5957#ifdef _SC_XOPEN_CRYPT
5958 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5959#endif
5960#ifdef _SC_XOPEN_ENH_I18N
5961 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5962#endif
5963#ifdef _SC_XOPEN_LEGACY
5964 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5965#endif
5966#ifdef _SC_XOPEN_REALTIME
5967 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5968#endif
5969#ifdef _SC_XOPEN_REALTIME_THREADS
5970 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5971#endif
5972#ifdef _SC_XOPEN_SHM
5973 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5974#endif
5975#ifdef _SC_XOPEN_UNIX
5976 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5977#endif
5978#ifdef _SC_XOPEN_VERSION
5979 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5980#endif
5981#ifdef _SC_XOPEN_XCU_VERSION
5982 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5983#endif
5984#ifdef _SC_XOPEN_XPG2
5985 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5986#endif
5987#ifdef _SC_XOPEN_XPG3
5988 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5989#endif
5990#ifdef _SC_XOPEN_XPG4
5991 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5992#endif
5993};
5994
5995static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005996conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005997{
5998 return conv_confname(arg, valuep, posix_constants_sysconf,
5999 sizeof(posix_constants_sysconf)
6000 / sizeof(struct constdef));
6001}
6002
6003static char posix_sysconf__doc__[] = "\
6004sysconf(name) -> integer\n\
6005Return an integer-valued system configuration variable.";
6006
6007static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006008posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006009{
6010 PyObject *result = NULL;
6011 int name;
6012
6013 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6014 int value;
6015
6016 errno = 0;
6017 value = sysconf(name);
6018 if (value == -1 && errno != 0)
6019 posix_error();
6020 else
6021 result = PyInt_FromLong(value);
6022 }
6023 return result;
6024}
6025#endif
6026
6027
Fred Drakebec628d1999-12-15 18:31:10 +00006028/* This code is used to ensure that the tables of configuration value names
6029 * are in sorted order as required by conv_confname(), and also to build the
6030 * the exported dictionaries that are used to publish information about the
6031 * names available on the host platform.
6032 *
6033 * Sorting the table at runtime ensures that the table is properly ordered
6034 * when used, even for platforms we're not able to test on. It also makes
6035 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006036 */
Fred Drakebec628d1999-12-15 18:31:10 +00006037
6038static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006039cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006040{
6041 const struct constdef *c1 =
6042 (const struct constdef *) v1;
6043 const struct constdef *c2 =
6044 (const struct constdef *) v2;
6045
6046 return strcmp(c1->name, c2->name);
6047}
6048
6049static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006050setup_confname_table(struct constdef *table, size_t tablesize,
6051 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00006052{
Fred Drakebec628d1999-12-15 18:31:10 +00006053 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006054 size_t i;
6055 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00006056
6057 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6058 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006059 if (d == NULL)
6060 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006061
Barry Warsaw3155db32000-04-13 15:20:40 +00006062 for (i=0; i < tablesize; ++i) {
6063 PyObject *o = PyInt_FromLong(table[i].value);
6064 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6065 Py_XDECREF(o);
6066 Py_DECREF(d);
6067 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006068 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006069 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006070 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006071 status = PyDict_SetItemString(moddict, tablename, d);
6072 Py_DECREF(d);
6073 return status;
Fred Draked86ed291999-12-15 15:34:33 +00006074}
6075
Fred Drakebec628d1999-12-15 18:31:10 +00006076/* Return -1 on failure, 0 on success. */
6077static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006078setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00006079{
6080#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006081 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006082 sizeof(posix_constants_pathconf)
6083 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006084 "pathconf_names", moddict))
6085 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006086#endif
6087#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006088 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006089 sizeof(posix_constants_confstr)
6090 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006091 "confstr_names", moddict))
6092 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006093#endif
6094#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006095 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006096 sizeof(posix_constants_sysconf)
6097 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006098 "sysconf_names", moddict))
6099 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006100#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006101 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006102}
Fred Draked86ed291999-12-15 15:34:33 +00006103
6104
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006105static char posix_abort__doc__[] = "\
6106abort() -> does not return!\n\
6107Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
6108in the hardest way possible on the hosting operating system.";
6109
6110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006111posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006112{
6113 if (!PyArg_ParseTuple(args, ":abort"))
6114 return NULL;
6115 abort();
6116 /*NOTREACHED*/
6117 Py_FatalError("abort() called from Python code didn't abort!");
6118 return NULL;
6119}
Fred Drakebec628d1999-12-15 18:31:10 +00006120
Tim Petersf58a7aa2000-09-22 10:05:54 +00006121#ifdef MS_WIN32
6122static char win32_startfile__doc__[] = "\
6123startfile(filepath) - Start a file with its associated application.\n\
6124\n\
6125This acts like double-clicking the file in Explorer, or giving the file\n\
6126name as an argument to the DOS \"start\" command: the file is opened\n\
6127with whatever application (if any) its extension is associated.\n\
6128\n\
6129startfile returns as soon as the associated application is launched.\n\
6130There is no option to wait for the application to close, and no way\n\
6131to retrieve the application's exit status.\n\
6132\n\
6133The filepath is relative to the current directory. If you want to use\n\
6134an absolute path, make sure the first character is not a slash (\"/\");\n\
6135the underlying Win32 ShellExecute function doesn't work if it is.";
6136
6137static PyObject *
6138win32_startfile(PyObject *self, PyObject *args)
6139{
6140 char *filepath;
6141 HINSTANCE rc;
6142 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6143 return NULL;
6144 Py_BEGIN_ALLOW_THREADS
6145 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6146 Py_END_ALLOW_THREADS
6147 if (rc <= (HINSTANCE)32)
6148 return win32_error("startfile", filepath);
6149 Py_INCREF(Py_None);
6150 return Py_None;
6151}
6152#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006153
6154static PyMethodDef posix_methods[] = {
6155 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6156#ifdef HAVE_TTYNAME
6157 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6158#endif
6159 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6160 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006161#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006162 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006163#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006164#ifdef HAVE_CHROOT
6165 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6166#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006167#ifdef HAVE_CTERMID
6168 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6169#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006170#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006171 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006172#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006173#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006174 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006175#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006176 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6177 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6178 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006179#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006180 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006181#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006182#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006183 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006184#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006185 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6186 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6187 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006188#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006189 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006190#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006191#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006192 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006193#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006194 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006195#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006196 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006197#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006198 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6199 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6200 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006201#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006202 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006203#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006204 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006205#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006206 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6207 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006208#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006209#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006210 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6211 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006212#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006213#ifdef HAVE_FORK1
6214 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6215#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006216#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006217 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006218#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006219#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006220 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006221#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006222#ifdef HAVE_FORKPTY
6223 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6224#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006225#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006226 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006227#endif /* HAVE_GETEGID */
6228#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006229 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006230#endif /* HAVE_GETEUID */
6231#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006232 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006233#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006234#ifdef HAVE_GETGROUPS
6235 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6236#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006237 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006238#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006239 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006240#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006241#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006242 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006243#endif /* HAVE_GETPPID */
6244#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006245 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006246#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006247#ifdef HAVE_GETLOGIN
6248 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6249#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006250#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006251 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006252#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006253#ifdef HAVE_KILLPG
6254 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6255#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006256#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006257 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006258#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006259#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006260 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006261#ifdef MS_WIN32
6262 {"popen2", win32_popen2, METH_VARARGS},
6263 {"popen3", win32_popen3, METH_VARARGS},
6264 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006265 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006266#else
6267#if defined(PYOS_OS2) && defined(PYCC_GCC)
6268 {"popen2", os2emx_popen2, METH_VARARGS},
6269 {"popen3", os2emx_popen3, METH_VARARGS},
6270 {"popen4", os2emx_popen4, METH_VARARGS},
6271#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006272#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006273#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006274#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006275 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006276#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006277#ifdef HAVE_SETEUID
6278 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6279#endif /* HAVE_SETEUID */
6280#ifdef HAVE_SETEGID
6281 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6282#endif /* HAVE_SETEGID */
6283#ifdef HAVE_SETREUID
6284 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6285#endif /* HAVE_SETREUID */
6286#ifdef HAVE_SETREGID
6287 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6288#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006289#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006290 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006291#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006292#ifdef HAVE_SETGROUPS
6293 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6294#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006295#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006296 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006297#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006298#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006299 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006300#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006301#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006302 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006303#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006304#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006305 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006306#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006307#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006308 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006309#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006310#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006311 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006312#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006313#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006314 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006315#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006316 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6317 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6318 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6319 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6320 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6321 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6322 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6323 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6324 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006325 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006326#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006327 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006328#endif
6329#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006330 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006331#endif
6332#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006333 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006334#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006335#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006336 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006337#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006338#ifdef HAVE_UNSETENV
6339 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6340#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006341#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006342 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006343#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006344#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006345 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006346#endif
6347#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006348 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006349#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006350#ifdef HAVE_SYS_WAIT_H
6351#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006352 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006353#endif /* WIFSTOPPED */
6354#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006355 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006356#endif /* WIFSIGNALED */
6357#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006358 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006359#endif /* WIFEXITED */
6360#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006361 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006362#endif /* WEXITSTATUS */
6363#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006364 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006365#endif /* WTERMSIG */
6366#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006367 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006368#endif /* WSTOPSIG */
6369#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006370#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006371 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006372#endif
6373#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006374 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006375#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006376#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006377 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6378#endif
6379#ifdef HAVE_TEMPNAM
6380 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6381#endif
6382#ifdef HAVE_TMPNAM
6383 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6384#endif
Fred Drakec9680921999-12-13 16:37:25 +00006385#ifdef HAVE_CONFSTR
6386 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6387#endif
6388#ifdef HAVE_SYSCONF
6389 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6390#endif
6391#ifdef HAVE_FPATHCONF
6392 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6393#endif
6394#ifdef HAVE_PATHCONF
6395 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6396#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006397 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00006398#ifdef MS_WIN32
6399 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6400#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006401 {NULL, NULL} /* Sentinel */
6402};
6403
6404
Barry Warsaw4a342091996-12-19 23:50:02 +00006405static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006406ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006407{
6408 PyObject* v = PyInt_FromLong(value);
6409 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
6410 return -1; /* triggers fatal error */
6411
6412 Py_DECREF(v);
6413 return 0;
6414}
6415
Guido van Rossumd48f2521997-12-05 22:19:34 +00006416#if defined(PYOS_OS2)
6417/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
6418static int insertvalues(PyObject *d)
6419{
6420 APIRET rc;
6421 ULONG values[QSV_MAX+1];
6422 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006423 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006424
6425 Py_BEGIN_ALLOW_THREADS
6426 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6427 Py_END_ALLOW_THREADS
6428
6429 if (rc != NO_ERROR) {
6430 os2_error(rc);
6431 return -1;
6432 }
6433
6434 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6435 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
6436 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6437 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6438 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6439 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
6440 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
6441
6442 switch (values[QSV_VERSION_MINOR]) {
6443 case 0: ver = "2.00"; break;
6444 case 10: ver = "2.10"; break;
6445 case 11: ver = "2.11"; break;
6446 case 30: ver = "3.00"; break;
6447 case 40: ver = "4.00"; break;
6448 case 50: ver = "5.00"; break;
6449 default:
Tim Peters885d4572001-11-28 20:27:42 +00006450 PyOS_snprintf(tmp, sizeof(tmp),
6451 "%d-%d", values[QSV_VERSION_MAJOR],
6452 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006453 ver = &tmp[0];
6454 }
6455
6456 /* Add Indicator of the Version of the Operating System */
6457 v = PyString_FromString(ver);
6458 if (!v || PyDict_SetItemString(d, "version", v) < 0)
6459 return -1;
6460 Py_DECREF(v);
6461
6462 /* Add Indicator of Which Drive was Used to Boot the System */
6463 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6464 tmp[1] = ':';
6465 tmp[2] = '\0';
6466
6467 v = PyString_FromString(tmp);
6468 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
6469 return -1;
6470 Py_DECREF(v);
6471
6472 return 0;
6473}
6474#endif
6475
Barry Warsaw4a342091996-12-19 23:50:02 +00006476static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006477all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006478{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006479#ifdef F_OK
6480 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006481#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006482#ifdef R_OK
6483 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006484#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006485#ifdef W_OK
6486 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006487#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006488#ifdef X_OK
6489 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006490#endif
Fred Drakec9680921999-12-13 16:37:25 +00006491#ifdef NGROUPS_MAX
6492 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6493#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006494#ifdef TMP_MAX
6495 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6496#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006497#ifdef WNOHANG
6498 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006499#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006500#ifdef O_RDONLY
6501 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6502#endif
6503#ifdef O_WRONLY
6504 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6505#endif
6506#ifdef O_RDWR
6507 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6508#endif
6509#ifdef O_NDELAY
6510 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6511#endif
6512#ifdef O_NONBLOCK
6513 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6514#endif
6515#ifdef O_APPEND
6516 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6517#endif
6518#ifdef O_DSYNC
6519 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6520#endif
6521#ifdef O_RSYNC
6522 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6523#endif
6524#ifdef O_SYNC
6525 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6526#endif
6527#ifdef O_NOCTTY
6528 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6529#endif
6530#ifdef O_CREAT
6531 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6532#endif
6533#ifdef O_EXCL
6534 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6535#endif
6536#ifdef O_TRUNC
6537 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6538#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006539#ifdef O_BINARY
6540 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6541#endif
6542#ifdef O_TEXT
6543 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6544#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006545#ifdef O_LARGEFILE
6546 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6547#endif
6548
Tim Peters5aa91602002-01-30 05:46:57 +00006549/* MS Windows */
6550#ifdef O_NOINHERIT
6551 /* Don't inherit in child processes. */
6552 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6553#endif
6554#ifdef _O_SHORT_LIVED
6555 /* Optimize for short life (keep in memory). */
6556 /* MS forgot to define this one with a non-underscore form too. */
6557 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6558#endif
6559#ifdef O_TEMPORARY
6560 /* Automatically delete when last handle is closed. */
6561 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6562#endif
6563#ifdef O_RANDOM
6564 /* Optimize for random access. */
6565 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6566#endif
6567#ifdef O_SEQUENTIAL
6568 /* Optimize for sequential access. */
6569 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6570#endif
6571
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006572/* GNU extensions. */
6573#ifdef O_DIRECT
6574 /* Direct disk access. */
6575 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6576#endif
6577#ifdef O_DIRECTORY
6578 /* Must be a directory. */
6579 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6580#endif
6581#ifdef O_NOFOLLOW
6582 /* Do not follow links. */
6583 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6584#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006585
Guido van Rossum246bc171999-02-01 23:54:31 +00006586#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006587#if defined(PYOS_OS2) && defined(PYCC_GCC)
6588 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6589 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6590 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6591 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6592 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6593 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6594 if (ins(d, "P_PM", (long)P_PM)) return -1;
6595 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6596 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6597 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6598 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6599 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6600 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6601 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6602 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6603 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6604 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6605 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6606 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6607 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6608#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006609 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6610 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6611 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6612 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6613 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006614#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006615#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006616
Guido van Rossumd48f2521997-12-05 22:19:34 +00006617#if defined(PYOS_OS2)
6618 if (insertvalues(d)) return -1;
6619#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006620 return 0;
6621}
6622
6623
Tim Peters5aa91602002-01-30 05:46:57 +00006624#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006625#define INITFUNC initnt
6626#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006627
6628#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006629#define INITFUNC initos2
6630#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006631
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006632#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006633#define INITFUNC initposix
6634#define MODNAME "posix"
6635#endif
6636
Guido van Rossum3886bb61998-12-04 18:50:17 +00006637DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006638INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006639{
Barry Warsaw53699e91996-12-10 23:23:01 +00006640 PyObject *m, *d, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006641
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006642 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006643 posix_methods,
6644 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006645 (PyObject *)NULL,
6646 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00006647 d = PyModule_GetDict(m);
Tim Peters5aa91602002-01-30 05:46:57 +00006648
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006649 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006650 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00006651 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006652 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006653 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006654
Barry Warsaw4a342091996-12-19 23:50:02 +00006655 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00006656 return;
6657
Fred Drakebec628d1999-12-15 18:31:10 +00006658 if (setup_confname_tables(d))
6659 return;
6660
Barry Warsawca74da41999-02-09 19:31:45 +00006661 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006662
Guido van Rossumb3d39562000-01-31 18:41:26 +00006663#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006664 if (posix_putenv_garbage == NULL)
6665 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006666#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006667
Guido van Rossum14648392001-12-08 18:02:58 +00006668 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006669 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
6670 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
6671
Guido van Rossum14648392001-12-08 18:02:58 +00006672 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006673 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Guido van Rossumbb2501f2001-12-27 16:23:28 +00006674 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006675}