blob: 5b80479bf85242dab4dfbb5ef07398cb3466aaaa [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]);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000983
Tim Peters5aa91602002-01-30 05:46:57 +0000984 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +0000985 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000986 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +0000987 if (len > 0) {
988 char ch = namebuf[len-1];
989 if (ch != SEP && ch != ALTSEP && ch != ':')
990 namebuf[len++] = '/';
991 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000992 strcpy(namebuf + len, "*.*");
993
Barry Warsaw53699e91996-12-10 23:23:01 +0000994 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000995 return NULL;
996
997 hFindFile = FindFirstFile(namebuf, &FileData);
998 if (hFindFile == INVALID_HANDLE_VALUE) {
999 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001000 if (errno == ERROR_FILE_NOT_FOUND)
1001 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001002 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001003 }
1004 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001005 if (FileData.cFileName[0] == '.' &&
1006 (FileData.cFileName[1] == '\0' ||
1007 FileData.cFileName[1] == '.' &&
1008 FileData.cFileName[2] == '\0'))
1009 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001010 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001011 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001012 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001013 d = NULL;
1014 break;
1015 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001016 if (PyList_Append(d, v) != 0) {
1017 Py_DECREF(v);
1018 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001019 d = NULL;
1020 break;
1021 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001022 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001023 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1024
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001025 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001026 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001027
1028 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001029
Tim Peters0bb44a42000-09-15 07:44:49 +00001030#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001031
1032#ifndef MAX_PATH
1033#define MAX_PATH 250
1034#endif
1035 char *name, *pt;
1036 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001037 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001038 char namebuf[MAX_PATH+5];
1039 struct _find_t ep;
1040
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001041 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001042 return NULL;
1043 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001044 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001045 return NULL;
1046 }
1047 strcpy(namebuf, name);
1048 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001049 if (*pt == ALTSEP)
1050 *pt = SEP;
1051 if (namebuf[len-1] != SEP)
1052 namebuf[len++] = SEP;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001053 strcpy(namebuf + len, "*.*");
1054
Barry Warsaw53699e91996-12-10 23:23:01 +00001055 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001056 return NULL;
1057
1058 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001059 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1060 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001061 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001062 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001063 }
1064 do {
1065 if (ep.name[0] == '.' &&
1066 (ep.name[1] == '\0' ||
1067 ep.name[1] == '.' &&
1068 ep.name[2] == '\0'))
1069 continue;
1070 strcpy(namebuf, ep.name);
1071 for (pt = namebuf; *pt; pt++)
1072 if (isupper(*pt))
1073 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001074 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001075 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001076 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001077 d = NULL;
1078 break;
1079 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001080 if (PyList_Append(d, v) != 0) {
1081 Py_DECREF(v);
1082 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001083 d = NULL;
1084 break;
1085 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001086 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001087 } while (_dos_findnext(&ep) == 0);
1088
1089 return d;
1090
Tim Peters0bb44a42000-09-15 07:44:49 +00001091#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001092
1093#ifndef MAX_PATH
1094#define MAX_PATH CCHMAXPATH
1095#endif
1096 char *name, *pt;
1097 int len;
1098 PyObject *d, *v;
1099 char namebuf[MAX_PATH+5];
1100 HDIR hdir = 1;
1101 ULONG srchcnt = 1;
1102 FILEFINDBUF3 ep;
1103 APIRET rc;
1104
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001105 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001106 return NULL;
1107 if (len >= MAX_PATH) {
1108 PyErr_SetString(PyExc_ValueError, "path too long");
1109 return NULL;
1110 }
1111 strcpy(namebuf, name);
1112 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001113 if (*pt == ALTSEP)
1114 *pt = SEP;
1115 if (namebuf[len-1] != SEP)
1116 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001117 strcpy(namebuf + len, "*.*");
1118
1119 if ((d = PyList_New(0)) == NULL)
1120 return NULL;
1121
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001122 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1123 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001124 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001125 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1126 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1127 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001128
1129 if (rc != NO_ERROR) {
1130 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001131 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001132 }
1133
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001134 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001135 do {
1136 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001137 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001138 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001139
1140 strcpy(namebuf, ep.achName);
1141
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001142 /* Leave Case of Name Alone -- In Native Form */
1143 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001144
1145 v = PyString_FromString(namebuf);
1146 if (v == NULL) {
1147 Py_DECREF(d);
1148 d = NULL;
1149 break;
1150 }
1151 if (PyList_Append(d, v) != 0) {
1152 Py_DECREF(v);
1153 Py_DECREF(d);
1154 d = NULL;
1155 break;
1156 }
1157 Py_DECREF(v);
1158 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1159 }
1160
1161 return d;
1162#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001163
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001164 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001165 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001166 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001167 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001168 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001169 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001170 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001171 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001172 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001173 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001174 closedir(dirp);
1175 return NULL;
1176 }
1177 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001178 if (ep->d_name[0] == '.' &&
1179 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001180 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001181 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001182 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001183 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001184 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185 d = NULL;
1186 break;
1187 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001188 if (PyList_Append(d, v) != 0) {
1189 Py_DECREF(v);
1190 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191 d = NULL;
1192 break;
1193 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001194 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195 }
1196 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001197
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001198 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001199
Tim Peters0bb44a42000-09-15 07:44:49 +00001200#endif /* which OS */
1201} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001202
Mark Hammondef8b6542001-05-13 08:04:26 +00001203#ifdef MS_WIN32
1204/* A helper function for abspath on win32 */
1205static PyObject *
1206posix__getfullpathname(PyObject *self, PyObject *args)
1207{
1208 /* assume encoded strings wont more than double no of chars */
1209 char inbuf[MAX_PATH*2];
1210 char *inbufp = inbuf;
1211 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1212 char outbuf[MAX_PATH*2];
1213 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001214 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1215 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001216 &insize))
1217 return NULL;
1218 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1219 outbuf, &temp))
1220 return win32_error("GetFullPathName", inbuf);
1221 return PyString_FromString(outbuf);
1222} /* end of posix__getfullpathname */
1223#endif /* MS_WIN32 */
1224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001225static char posix_mkdir__doc__[] =
1226"mkdir(path [, mode=0777]) -> None\n\
1227Create a directory.";
1228
Barry Warsaw53699e91996-12-10 23:23:01 +00001229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001230posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001231{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001232 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001233 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001234 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001235 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001236 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001237 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001238 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001239#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001240 res = mkdir(path);
1241#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001242 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001243#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001244 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001245 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001246 return posix_error_with_allocated_filename(path);
1247 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001248 Py_INCREF(Py_None);
1249 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001250}
1251
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001252
Guido van Rossumb6775db1994-08-01 11:34:53 +00001253#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001254#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1255#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1256#include <sys/resource.h>
1257#endif
1258#endif
1259
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001260static char posix_nice__doc__[] =
1261"nice(inc) -> new_priority\n\
1262Decrease the priority of process and return new priority.";
1263
Barry Warsaw53699e91996-12-10 23:23:01 +00001264static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001265posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001266{
1267 int increment, value;
1268
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001269 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001270 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001271
1272 /* There are two flavours of 'nice': one that returns the new
1273 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001274 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1275 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001276
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001277 If we are of the nice family that returns the new priority, we
1278 need to clear errno before the call, and check if errno is filled
1279 before calling posix_error() on a returnvalue of -1, because the
1280 -1 may be the actual new priority! */
1281
1282 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001283 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001284#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001285 if (value == 0)
1286 value = getpriority(PRIO_PROCESS, 0);
1287#endif
1288 if (value == -1 && errno != 0)
1289 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001290 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001291 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001292}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001293#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001294
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001295
1296static char posix_rename__doc__[] =
1297"rename(old, new) -> None\n\
1298Rename a file or directory.";
1299
Barry Warsaw53699e91996-12-10 23:23:01 +00001300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001301posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001302{
Mark Hammondef8b6542001-05-13 08:04:26 +00001303 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001304}
1305
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001306
1307static char posix_rmdir__doc__[] =
1308"rmdir(path) -> None\n\
1309Remove a directory.";
1310
Barry Warsaw53699e91996-12-10 23:23:01 +00001311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001312posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001313{
Mark Hammondef8b6542001-05-13 08:04:26 +00001314 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001315}
1316
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001317
1318static char posix_stat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00001319"stat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
1320 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001321Perform a stat system call on the given path.";
1322
Barry Warsaw53699e91996-12-10 23:23:01 +00001323static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001324posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001325{
Mark Hammondef8b6542001-05-13 08:04:26 +00001326 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001327}
1328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001329
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001330#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001331static char posix_system__doc__[] =
1332"system(command) -> exit_status\n\
1333Execute the command (a string) in a subshell.";
1334
Barry Warsaw53699e91996-12-10 23:23:01 +00001335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001336posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001337{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001338 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001339 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001340 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001342 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001343 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001344 Py_END_ALLOW_THREADS
1345 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001347#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001348
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001349
1350static char posix_umask__doc__[] =
1351"umask(new_mask) -> old_mask\n\
1352Set the current numeric umask and return the previous umask.";
1353
Barry Warsaw53699e91996-12-10 23:23:01 +00001354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001355posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001356{
1357 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001358 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001359 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001360 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001361 if (i < 0)
1362 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001363 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364}
1365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001366
1367static char posix_unlink__doc__[] =
1368"unlink(path) -> None\n\
1369Remove a file (same as remove(path)).";
1370
1371static char posix_remove__doc__[] =
1372"remove(path) -> None\n\
1373Remove a file (same as unlink(path)).";
1374
Barry Warsaw53699e91996-12-10 23:23:01 +00001375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001376posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001377{
Mark Hammondef8b6542001-05-13 08:04:26 +00001378 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001379}
1380
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001381
Guido van Rossumb6775db1994-08-01 11:34:53 +00001382#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001383static char posix_uname__doc__[] =
1384"uname() -> (sysname, nodename, release, version, machine)\n\
1385Return a tuple identifying the current operating system.";
1386
Barry Warsaw53699e91996-12-10 23:23:01 +00001387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001388posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001389{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001390 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001391 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001392 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001393 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001394 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001395 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001396 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001397 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001398 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001399 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001400 u.sysname,
1401 u.nodename,
1402 u.release,
1403 u.version,
1404 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001405}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001406#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001407
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001408
1409static char posix_utime__doc__[] =
1410"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001411utime(path, None) -> None\n\
1412Set the access and modified time of the file to the given values. If the\n\
1413second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001414
Barry Warsaw53699e91996-12-10 23:23:01 +00001415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001416posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001417{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001418 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001419 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001420 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001421 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001422
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001423/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001424#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001425 struct utimbuf buf;
1426#define ATIME buf.actime
1427#define MTIME buf.modtime
1428#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001429#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001430 time_t buf[2];
1431#define ATIME buf[0]
1432#define MTIME buf[1]
1433#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001434#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001435
Barry Warsaw3cef8562000-05-01 16:17:24 +00001436 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001437 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001438 if (arg == Py_None) {
1439 /* optional time values not given */
1440 Py_BEGIN_ALLOW_THREADS
1441 res = utime(path, NULL);
1442 Py_END_ALLOW_THREADS
1443 }
1444 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1445 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001446 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001447 return NULL;
1448 }
1449 else {
1450 ATIME = atime;
1451 MTIME = mtime;
1452 Py_BEGIN_ALLOW_THREADS
1453 res = utime(path, UTIME_ARG);
1454 Py_END_ALLOW_THREADS
1455 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001456 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001457 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001458 Py_INCREF(Py_None);
1459 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001460#undef UTIME_ARG
1461#undef ATIME
1462#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001463}
1464
Guido van Rossum85e3b011991-06-03 12:42:10 +00001465
Guido van Rossum3b066191991-06-04 19:40:25 +00001466/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001468static char posix__exit__doc__[] =
1469"_exit(status)\n\
1470Exit to the system with specified status, without normal exit processing.";
1471
Barry Warsaw53699e91996-12-10 23:23:01 +00001472static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001473posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001474{
1475 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001476 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001477 return NULL;
1478 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001479 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001480}
1481
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001482
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001483#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001484static char posix_execv__doc__[] =
1485"execv(path, args)\n\
1486Execute an executable path with arguments, replacing current process.\n\
1487\n\
1488 path: path of executable file\n\
1489 args: tuple or list of strings";
1490
Barry Warsaw53699e91996-12-10 23:23:01 +00001491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001492posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001493{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001494 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001495 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001496 char **argvlist;
1497 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001498 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001499
Guido van Rossum89b33251993-10-22 14:26:06 +00001500 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001501 argv is a list or tuple of strings. */
1502
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001503 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001504 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001505 if (PyList_Check(argv)) {
1506 argc = PyList_Size(argv);
1507 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001508 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001509 else if (PyTuple_Check(argv)) {
1510 argc = PyTuple_Size(argv);
1511 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001512 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001513 else {
Fred Drake661ea262000-10-24 19:57:45 +00001514 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001515 return NULL;
1516 }
1517
1518 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001519 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001520 return NULL;
1521 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001522
Barry Warsaw53699e91996-12-10 23:23:01 +00001523 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001524 if (argvlist == NULL)
1525 return NULL;
1526 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001527 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1528 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001529 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001530 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001531 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001532
Guido van Rossum85e3b011991-06-03 12:42:10 +00001533 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001534 }
1535 argvlist[argc] = NULL;
1536
Guido van Rossumb6775db1994-08-01 11:34:53 +00001537#ifdef BAD_EXEC_PROTOTYPES
1538 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001539#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001540 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001541#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001542
Guido van Rossum85e3b011991-06-03 12:42:10 +00001543 /* If we get here it's definitely an error */
1544
Barry Warsaw53699e91996-12-10 23:23:01 +00001545 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001546 return posix_error();
1547}
1548
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001549
1550static char posix_execve__doc__[] =
1551"execve(path, args, env)\n\
1552Execute a path with arguments and environment, replacing current process.\n\
1553\n\
1554 path: path of executable file\n\
1555 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001556 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001557
Barry Warsaw53699e91996-12-10 23:23:01 +00001558static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001559posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001560{
1561 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001562 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001563 char **argvlist;
1564 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001565 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001566 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001567 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001568
1569 /* execve has three arguments: (path, argv, env), where
1570 argv is a list or tuple of strings and env is a dictionary
1571 like posix.environ. */
1572
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001573 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001574 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001575 if (PyList_Check(argv)) {
1576 argc = PyList_Size(argv);
1577 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001578 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001579 else if (PyTuple_Check(argv)) {
1580 argc = PyTuple_Size(argv);
1581 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001582 }
1583 else {
Fred Drake661ea262000-10-24 19:57:45 +00001584 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001585 return NULL;
1586 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001587 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001588 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001589 return NULL;
1590 }
1591
Guido van Rossum50422b42000-04-26 20:34:28 +00001592 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001593 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001594 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001595 return NULL;
1596 }
1597
Barry Warsaw53699e91996-12-10 23:23:01 +00001598 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001599 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001600 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 return NULL;
1602 }
1603 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001604 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001605 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001606 &argvlist[i]))
1607 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001608 goto fail_1;
1609 }
1610 }
1611 argvlist[argc] = NULL;
1612
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001613 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001615 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001616 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001617 goto fail_1;
1618 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001619 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001620 keys = PyMapping_Keys(env);
1621 vals = PyMapping_Values(env);
1622 if (!keys || !vals)
1623 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001624
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001625 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001626 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001627 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001628
1629 key = PyList_GetItem(keys, pos);
1630 val = PyList_GetItem(vals, pos);
1631 if (!key || !val)
1632 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001633
Fred Drake661ea262000-10-24 19:57:45 +00001634 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1635 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001636 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001637 goto fail_2;
1638 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001639
1640#if defined(PYOS_OS2)
1641 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1642 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1643#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001644 len = PyString_Size(key) + PyString_Size(val) + 2;
1645 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001646 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001647 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001648 goto fail_2;
1649 }
Tim Petersc8996f52001-12-03 20:41:00 +00001650 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001651 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001652#if defined(PYOS_OS2)
1653 }
1654#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001655 }
1656 envlist[envc] = 0;
1657
Guido van Rossumb6775db1994-08-01 11:34:53 +00001658
1659#ifdef BAD_EXEC_PROTOTYPES
1660 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001661#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001662 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001663#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001664
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001665 /* If we get here it's definitely an error */
1666
1667 (void) posix_error();
1668
1669 fail_2:
1670 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001671 PyMem_DEL(envlist[envc]);
1672 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001673 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001674 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001675 Py_XDECREF(vals);
1676 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001677 return NULL;
1678}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001679#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001680
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001681
Guido van Rossuma1065681999-01-25 23:20:23 +00001682#ifdef HAVE_SPAWNV
1683static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001684"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001685Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001686\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001687 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001688 path: path of executable file\n\
1689 args: tuple or list of strings";
1690
1691static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001692posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001693{
1694 char *path;
1695 PyObject *argv;
1696 char **argvlist;
1697 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001698 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001699 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001700
1701 /* spawnv has three arguments: (mode, path, argv), where
1702 argv is a list or tuple of strings. */
1703
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001704 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001705 return NULL;
1706 if (PyList_Check(argv)) {
1707 argc = PyList_Size(argv);
1708 getitem = PyList_GetItem;
1709 }
1710 else if (PyTuple_Check(argv)) {
1711 argc = PyTuple_Size(argv);
1712 getitem = PyTuple_GetItem;
1713 }
1714 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001715 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001716 return NULL;
1717 }
1718
1719 argvlist = PyMem_NEW(char *, argc+1);
1720 if (argvlist == NULL)
1721 return NULL;
1722 for (i = 0; i < argc; i++) {
1723 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1724 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001725 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001726 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001727 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001728 }
1729 }
1730 argvlist[argc] = NULL;
1731
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001732#if defined(PYOS_OS2) && defined(PYCC_GCC)
1733 Py_BEGIN_ALLOW_THREADS
1734 spawnval = spawnv(mode, path, argvlist);
1735 Py_END_ALLOW_THREADS
1736#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001737 if (mode == _OLD_P_OVERLAY)
1738 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001739
Tim Peters25059d32001-12-07 20:35:43 +00001740 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001741 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001742 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001743#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001744
Guido van Rossuma1065681999-01-25 23:20:23 +00001745 PyMem_DEL(argvlist);
1746
Fred Drake699f3522000-06-29 21:12:41 +00001747 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001748 return posix_error();
1749 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001750#if SIZEOF_LONG == SIZEOF_VOID_P
1751 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001752#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001753 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001754#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001755}
1756
1757
1758static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001759"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001760Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001761\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001762 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001763 path: path of executable file\n\
1764 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001765 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001766
1767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001768posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001769{
1770 char *path;
1771 PyObject *argv, *env;
1772 char **argvlist;
1773 char **envlist;
1774 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1775 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001776 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001777 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001778
1779 /* spawnve has four arguments: (mode, path, argv, env), where
1780 argv is a list or tuple of strings and env is a dictionary
1781 like posix.environ. */
1782
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001783 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001784 return NULL;
1785 if (PyList_Check(argv)) {
1786 argc = PyList_Size(argv);
1787 getitem = PyList_GetItem;
1788 }
1789 else if (PyTuple_Check(argv)) {
1790 argc = PyTuple_Size(argv);
1791 getitem = PyTuple_GetItem;
1792 }
1793 else {
Fred Drake661ea262000-10-24 19:57:45 +00001794 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001795 return NULL;
1796 }
1797 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001798 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001799 return NULL;
1800 }
1801
1802 argvlist = PyMem_NEW(char *, argc+1);
1803 if (argvlist == NULL) {
1804 PyErr_NoMemory();
1805 return NULL;
1806 }
1807 for (i = 0; i < argc; i++) {
1808 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001809 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001810 &argvlist[i]))
1811 {
1812 goto fail_1;
1813 }
1814 }
1815 argvlist[argc] = NULL;
1816
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001817 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001818 envlist = PyMem_NEW(char *, i + 1);
1819 if (envlist == NULL) {
1820 PyErr_NoMemory();
1821 goto fail_1;
1822 }
1823 envc = 0;
1824 keys = PyMapping_Keys(env);
1825 vals = PyMapping_Values(env);
1826 if (!keys || !vals)
1827 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001828
Guido van Rossuma1065681999-01-25 23:20:23 +00001829 for (pos = 0; pos < i; pos++) {
1830 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001831 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001832
1833 key = PyList_GetItem(keys, pos);
1834 val = PyList_GetItem(vals, pos);
1835 if (!key || !val)
1836 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001837
Fred Drake661ea262000-10-24 19:57:45 +00001838 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1839 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001840 {
1841 goto fail_2;
1842 }
Tim Petersc8996f52001-12-03 20:41:00 +00001843 len = PyString_Size(key) + PyString_Size(val) + 2;
1844 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001845 if (p == NULL) {
1846 PyErr_NoMemory();
1847 goto fail_2;
1848 }
Tim Petersc8996f52001-12-03 20:41:00 +00001849 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001850 envlist[envc++] = p;
1851 }
1852 envlist[envc] = 0;
1853
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001854#if defined(PYOS_OS2) && defined(PYCC_GCC)
1855 Py_BEGIN_ALLOW_THREADS
1856 spawnval = spawnve(mode, path, argvlist, envlist);
1857 Py_END_ALLOW_THREADS
1858#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001859 if (mode == _OLD_P_OVERLAY)
1860 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001861
1862 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001863 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001864 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001865#endif
Tim Peters25059d32001-12-07 20:35:43 +00001866
Fred Drake699f3522000-06-29 21:12:41 +00001867 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001868 (void) posix_error();
1869 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001870#if SIZEOF_LONG == SIZEOF_VOID_P
1871 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001872#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001873 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001874#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001875
1876 fail_2:
1877 while (--envc >= 0)
1878 PyMem_DEL(envlist[envc]);
1879 PyMem_DEL(envlist);
1880 fail_1:
1881 PyMem_DEL(argvlist);
1882 Py_XDECREF(vals);
1883 Py_XDECREF(keys);
1884 return res;
1885}
1886#endif /* HAVE_SPAWNV */
1887
1888
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001889#ifdef HAVE_FORK1
1890static char posix_fork1__doc__[] =
1891"fork1() -> pid\n\
1892Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1893\n\
1894Return 0 to child process and PID of child to parent process.";
1895
1896static PyObject *
1897posix_fork1(self, args)
1898 PyObject *self;
1899 PyObject *args;
1900{
1901 int pid;
1902 if (!PyArg_ParseTuple(args, ":fork1"))
1903 return NULL;
1904 pid = fork1();
1905 if (pid == -1)
1906 return posix_error();
1907 PyOS_AfterFork();
1908 return PyInt_FromLong((long)pid);
1909}
1910#endif
1911
1912
Guido van Rossumad0ee831995-03-01 10:34:45 +00001913#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001914static char posix_fork__doc__[] =
1915"fork() -> pid\n\
1916Fork a child process.\n\
1917\n\
1918Return 0 to child process and PID of child to parent process.";
1919
Barry Warsaw53699e91996-12-10 23:23:01 +00001920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001921posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001922{
1923 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001924 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001925 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001926 pid = fork();
1927 if (pid == -1)
1928 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001929 if (pid == 0)
1930 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001931 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001932}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001933#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001934
Fred Drake8cef4cf2000-06-28 16:40:38 +00001935#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1936#ifdef HAVE_PTY_H
1937#include <pty.h>
1938#else
1939#ifdef HAVE_LIBUTIL_H
1940#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001941#endif /* HAVE_LIBUTIL_H */
1942#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001943#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001944
Thomas Wouters70c21a12000-07-14 14:28:33 +00001945#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001946static char posix_openpty__doc__[] =
1947"openpty() -> (master_fd, slave_fd)\n\
1948Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1949
1950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001951posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001952{
1953 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001954#ifndef HAVE_OPENPTY
1955 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001956#endif
1957
Fred Drake8cef4cf2000-06-28 16:40:38 +00001958 if (!PyArg_ParseTuple(args, ":openpty"))
1959 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001960
1961#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001962 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1963 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001964#else
1965 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1966 if (slave_name == NULL)
1967 return posix_error();
1968
1969 slave_fd = open(slave_name, O_RDWR);
1970 if (slave_fd < 0)
1971 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001972#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001973
Fred Drake8cef4cf2000-06-28 16:40:38 +00001974 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001975
Fred Drake8cef4cf2000-06-28 16:40:38 +00001976}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001977#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001978
1979#ifdef HAVE_FORKPTY
1980static char posix_forkpty__doc__[] =
1981"forkpty() -> (pid, master_fd)\n\
1982Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1983Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1984To both, return fd of newly opened pseudo-terminal.\n";
1985
1986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001987posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001988{
1989 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00001990
Fred Drake8cef4cf2000-06-28 16:40:38 +00001991 if (!PyArg_ParseTuple(args, ":forkpty"))
1992 return NULL;
1993 pid = forkpty(&master_fd, NULL, NULL, NULL);
1994 if (pid == -1)
1995 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001996 if (pid == 0)
1997 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001998 return Py_BuildValue("(ii)", pid, master_fd);
1999}
2000#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002001
Guido van Rossumad0ee831995-03-01 10:34:45 +00002002#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002003static char posix_getegid__doc__[] =
2004"getegid() -> egid\n\
2005Return the current process's effective group id.";
2006
Barry Warsaw53699e91996-12-10 23:23:01 +00002007static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002008posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002009{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002010 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002011 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002012 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002013}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002014#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002015
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002016
Guido van Rossumad0ee831995-03-01 10:34:45 +00002017#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002018static char posix_geteuid__doc__[] =
2019"geteuid() -> euid\n\
2020Return the current process's effective user id.";
2021
Barry Warsaw53699e91996-12-10 23:23:01 +00002022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002023posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002024{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002025 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002026 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002027 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002028}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002029#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002031
Guido van Rossumad0ee831995-03-01 10:34:45 +00002032#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002033static char posix_getgid__doc__[] =
2034"getgid() -> gid\n\
2035Return the current process's group id.";
2036
Barry Warsaw53699e91996-12-10 23:23:01 +00002037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002038posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002039{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002040 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002041 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002042 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002043}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002044#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002046
2047static char posix_getpid__doc__[] =
2048"getpid() -> pid\n\
2049Return the current process id";
2050
Barry Warsaw53699e91996-12-10 23:23:01 +00002051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002052posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002053{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002054 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002055 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002056 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002057}
2058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059
Fred Drakec9680921999-12-13 16:37:25 +00002060#ifdef HAVE_GETGROUPS
2061static char posix_getgroups__doc__[] = "\
2062getgroups() -> list of group IDs\n\
2063Return list of supplemental group IDs for the process.";
2064
2065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002066posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002067{
2068 PyObject *result = NULL;
2069
2070 if (PyArg_ParseTuple(args, ":getgroups")) {
2071#ifdef NGROUPS_MAX
2072#define MAX_GROUPS NGROUPS_MAX
2073#else
2074 /* defined to be 16 on Solaris7, so this should be a small number */
2075#define MAX_GROUPS 64
2076#endif
2077 gid_t grouplist[MAX_GROUPS];
2078 int n;
2079
2080 n = getgroups(MAX_GROUPS, grouplist);
2081 if (n < 0)
2082 posix_error();
2083 else {
2084 result = PyList_New(n);
2085 if (result != NULL) {
2086 PyObject *o;
2087 int i;
2088 for (i = 0; i < n; ++i) {
2089 o = PyInt_FromLong((long)grouplist[i]);
2090 if (o == NULL) {
2091 Py_DECREF(result);
2092 result = NULL;
2093 break;
2094 }
2095 PyList_SET_ITEM(result, i, o);
2096 }
2097 }
2098 }
2099 }
2100 return result;
2101}
2102#endif
2103
Guido van Rossumb6775db1994-08-01 11:34:53 +00002104#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002105static char posix_getpgrp__doc__[] =
2106"getpgrp() -> pgrp\n\
2107Return the current process group id.";
2108
Barry Warsaw53699e91996-12-10 23:23:01 +00002109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002110posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002111{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002112 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002113 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002114#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002115 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002116#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002117 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002118#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002119}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002120#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122
Guido van Rossumb6775db1994-08-01 11:34:53 +00002123#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002124static char posix_setpgrp__doc__[] =
2125"setpgrp() -> None\n\
2126Make this process a session leader.";
2127
Barry Warsaw53699e91996-12-10 23:23:01 +00002128static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002129posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002130{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002131 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002132 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002133#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002134 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002135#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002136 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002137#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002138 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002139 Py_INCREF(Py_None);
2140 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002141}
2142
Guido van Rossumb6775db1994-08-01 11:34:53 +00002143#endif /* HAVE_SETPGRP */
2144
Guido van Rossumad0ee831995-03-01 10:34:45 +00002145#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002146static char posix_getppid__doc__[] =
2147"getppid() -> ppid\n\
2148Return the parent's process id.";
2149
Barry Warsaw53699e91996-12-10 23:23:01 +00002150static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002151posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002152{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002153 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002154 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002155 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002156}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002157#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002159
Fred Drake12c6e2d1999-12-14 21:25:03 +00002160#ifdef HAVE_GETLOGIN
2161static char posix_getlogin__doc__[] = "\
2162getlogin() -> string\n\
2163Return the actual login name.";
2164
2165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002166posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002167{
2168 PyObject *result = NULL;
2169
2170 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002171 char *name;
2172 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002173
Fred Drakea30680b2000-12-06 21:24:28 +00002174 errno = 0;
2175 name = getlogin();
2176 if (name == NULL) {
2177 if (errno)
2178 posix_error();
2179 else
2180 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002181 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002182 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002183 else
2184 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002185 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002186 }
2187 return result;
2188}
2189#endif
2190
Guido van Rossumad0ee831995-03-01 10:34:45 +00002191#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002192static char posix_getuid__doc__[] =
2193"getuid() -> uid\n\
2194Return the current process's user id.";
2195
Barry Warsaw53699e91996-12-10 23:23:01 +00002196static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002197posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002198{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002199 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002200 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002201 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002202}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002203#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002204
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002205
Guido van Rossumad0ee831995-03-01 10:34:45 +00002206#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002207static char posix_kill__doc__[] =
2208"kill(pid, sig) -> None\n\
2209Kill a process with a signal.";
2210
Barry Warsaw53699e91996-12-10 23:23:01 +00002211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002212posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002213{
2214 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002215 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002216 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002217#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002218 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2219 APIRET rc;
2220 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002221 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002222
2223 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2224 APIRET rc;
2225 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002226 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002227
2228 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002229 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002230#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002231 if (kill(pid, sig) == -1)
2232 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002233#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002234 Py_INCREF(Py_None);
2235 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002236}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002237#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002238
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002239#ifdef HAVE_KILLPG
2240static char posix_killpg__doc__[] =
2241"killpg(pgid, sig) -> None\n\
2242Kill a process group with a signal.";
2243
2244static PyObject *
2245posix_killpg(PyObject *self, PyObject *args)
2246{
2247 int pgid, sig;
2248 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2249 return NULL;
2250 if (killpg(pgid, sig) == -1)
2251 return posix_error();
2252 Py_INCREF(Py_None);
2253 return Py_None;
2254}
2255#endif
2256
Guido van Rossumc0125471996-06-28 18:55:32 +00002257#ifdef HAVE_PLOCK
2258
2259#ifdef HAVE_SYS_LOCK_H
2260#include <sys/lock.h>
2261#endif
2262
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002263static char posix_plock__doc__[] =
2264"plock(op) -> None\n\
2265Lock program segments into memory.";
2266
Barry Warsaw53699e91996-12-10 23:23:01 +00002267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002268posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002269{
2270 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002271 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002272 return NULL;
2273 if (plock(op) == -1)
2274 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002275 Py_INCREF(Py_None);
2276 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002277}
2278#endif
2279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002280
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002281#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002282static char posix_popen__doc__[] =
2283"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2284Open a pipe to/from a command returning a file object.";
2285
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002286#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002287#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002288static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002289async_system(const char *command)
2290{
2291 char *p, errormsg[256], args[1024];
2292 RESULTCODES rcodes;
2293 APIRET rc;
2294 char *shell = getenv("COMSPEC");
2295 if (!shell)
2296 shell = "cmd";
2297
2298 strcpy(args, shell);
2299 p = &args[ strlen(args)+1 ];
2300 strcpy(p, "/c ");
2301 strcat(p, command);
2302 p += strlen(p) + 1;
2303 *p = '\0';
2304
2305 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002306 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002307 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002308 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002309 &rcodes, shell);
2310 return rc;
2311}
2312
Guido van Rossumd48f2521997-12-05 22:19:34 +00002313static FILE *
2314popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002315{
2316 HFILE rhan, whan;
2317 FILE *retfd = NULL;
2318 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2319
Guido van Rossumd48f2521997-12-05 22:19:34 +00002320 if (rc != NO_ERROR) {
2321 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002322 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002323 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002324
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002325 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2326 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002327
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002328 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2329 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002330
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002331 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2332 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002333
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002334 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002335 }
2336
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002337 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2338 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002339
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002340 if (rc == NO_ERROR)
2341 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2342
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002343 close(oldfd); /* And Close Saved STDOUT Handle */
2344 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002345
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002346 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2347 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002348
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002349 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2350 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002351
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002352 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2353 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002354
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002355 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002356 }
2357
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002358 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2359 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002360
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002361 if (rc == NO_ERROR)
2362 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2363
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002364 close(oldfd); /* And Close Saved STDIN Handle */
2365 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002366
Guido van Rossumd48f2521997-12-05 22:19:34 +00002367 } else {
2368 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002369 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002370 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002371}
2372
2373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002374posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002375{
2376 char *name;
2377 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002378 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002379 FILE *fp;
2380 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002381 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002382 return NULL;
2383 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002384 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002385 Py_END_ALLOW_THREADS
2386 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002387 return os2_error(err);
2388
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002389 f = PyFile_FromFile(fp, name, mode, fclose);
2390 if (f != NULL)
2391 PyFile_SetBufSize(f, bufsize);
2392 return f;
2393}
2394
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002395#elif defined(PYCC_GCC)
2396
2397/* standard posix version of popen() support */
2398static PyObject *
2399posix_popen(PyObject *self, PyObject *args)
2400{
2401 char *name;
2402 char *mode = "r";
2403 int bufsize = -1;
2404 FILE *fp;
2405 PyObject *f;
2406 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2407 return NULL;
2408 Py_BEGIN_ALLOW_THREADS
2409 fp = popen(name, mode);
2410 Py_END_ALLOW_THREADS
2411 if (fp == NULL)
2412 return posix_error();
2413 f = PyFile_FromFile(fp, name, mode, pclose);
2414 if (f != NULL)
2415 PyFile_SetBufSize(f, bufsize);
2416 return f;
2417}
2418
2419/* fork() under OS/2 has lots'o'warts
2420 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2421 * most of this code is a ripoff of the win32 code, but using the
2422 * capabilities of EMX's C library routines
2423 */
2424
2425/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2426#define POPEN_1 1
2427#define POPEN_2 2
2428#define POPEN_3 3
2429#define POPEN_4 4
2430
2431static PyObject *_PyPopen(char *, int, int, int);
2432static int _PyPclose(FILE *file);
2433
2434/*
2435 * Internal dictionary mapping popen* file pointers to process handles,
2436 * for use when retrieving the process exit code. See _PyPclose() below
2437 * for more information on this dictionary's use.
2438 */
2439static PyObject *_PyPopenProcs = NULL;
2440
2441/* os2emx version of popen2()
2442 *
2443 * The result of this function is a pipe (file) connected to the
2444 * process's stdin, and a pipe connected to the process's stdout.
2445 */
2446
2447static PyObject *
2448os2emx_popen2(PyObject *self, PyObject *args)
2449{
2450 PyObject *f;
2451 int tm=0;
2452
2453 char *cmdstring;
2454 char *mode = "t";
2455 int bufsize = -1;
2456 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2457 return NULL;
2458
2459 if (*mode == 't')
2460 tm = O_TEXT;
2461 else if (*mode != 'b') {
2462 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2463 return NULL;
2464 } else
2465 tm = O_BINARY;
2466
2467 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2468
2469 return f;
2470}
2471
2472/*
2473 * Variation on os2emx.popen2
2474 *
2475 * The result of this function is 3 pipes - the process's stdin,
2476 * stdout and stderr
2477 */
2478
2479static PyObject *
2480os2emx_popen3(PyObject *self, PyObject *args)
2481{
2482 PyObject *f;
2483 int tm = 0;
2484
2485 char *cmdstring;
2486 char *mode = "t";
2487 int bufsize = -1;
2488 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2489 return NULL;
2490
2491 if (*mode == 't')
2492 tm = O_TEXT;
2493 else if (*mode != 'b') {
2494 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2495 return NULL;
2496 } else
2497 tm = O_BINARY;
2498
2499 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2500
2501 return f;
2502}
2503
2504/*
2505 * Variation on os2emx.popen2
2506 *
2507 * The result of this function is 2 pipes - the processes stdin,
2508 * and stdout+stderr combined as a single pipe.
2509 */
2510
2511static PyObject *
2512os2emx_popen4(PyObject *self, PyObject *args)
2513{
2514 PyObject *f;
2515 int tm = 0;
2516
2517 char *cmdstring;
2518 char *mode = "t";
2519 int bufsize = -1;
2520 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2521 return NULL;
2522
2523 if (*mode == 't')
2524 tm = O_TEXT;
2525 else if (*mode != 'b') {
2526 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2527 return NULL;
2528 } else
2529 tm = O_BINARY;
2530
2531 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2532
2533 return f;
2534}
2535
2536/* a couple of structures for convenient handling of multiple
2537 * file handles and pipes
2538 */
2539struct file_ref
2540{
2541 int handle;
2542 int flags;
2543};
2544
2545struct pipe_ref
2546{
2547 int rd;
2548 int wr;
2549};
2550
2551/* The following code is derived from the win32 code */
2552
2553static PyObject *
2554_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2555{
2556 struct file_ref stdio[3];
2557 struct pipe_ref p_fd[3];
2558 FILE *p_s[3];
2559 int file_count, i, pipe_err, pipe_pid;
2560 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2561 PyObject *f, *p_f[3];
2562
2563 /* file modes for subsequent fdopen's on pipe handles */
2564 if (mode == O_TEXT)
2565 {
2566 rd_mode = "rt";
2567 wr_mode = "wt";
2568 }
2569 else
2570 {
2571 rd_mode = "rb";
2572 wr_mode = "wb";
2573 }
2574
2575 /* prepare shell references */
2576 if ((shell = getenv("EMXSHELL")) == NULL)
2577 if ((shell = getenv("COMSPEC")) == NULL)
2578 {
2579 errno = ENOENT;
2580 return posix_error();
2581 }
2582
2583 sh_name = _getname(shell);
2584 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2585 opt = "/c";
2586 else
2587 opt = "-c";
2588
2589 /* save current stdio fds + their flags, and set not inheritable */
2590 i = pipe_err = 0;
2591 while (pipe_err >= 0 && i < 3)
2592 {
2593 pipe_err = stdio[i].handle = dup(i);
2594 stdio[i].flags = fcntl(i, F_GETFD, 0);
2595 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2596 i++;
2597 }
2598 if (pipe_err < 0)
2599 {
2600 /* didn't get them all saved - clean up and bail out */
2601 int saved_err = errno;
2602 while (i-- > 0)
2603 {
2604 close(stdio[i].handle);
2605 }
2606 errno = saved_err;
2607 return posix_error();
2608 }
2609
2610 /* create pipe ends */
2611 file_count = 2;
2612 if (n == POPEN_3)
2613 file_count = 3;
2614 i = pipe_err = 0;
2615 while ((pipe_err == 0) && (i < file_count))
2616 pipe_err = pipe((int *)&p_fd[i++]);
2617 if (pipe_err < 0)
2618 {
2619 /* didn't get them all made - clean up and bail out */
2620 while (i-- > 0)
2621 {
2622 close(p_fd[i].wr);
2623 close(p_fd[i].rd);
2624 }
2625 errno = EPIPE;
2626 return posix_error();
2627 }
2628
2629 /* change the actual standard IO streams over temporarily,
2630 * making the retained pipe ends non-inheritable
2631 */
2632 pipe_err = 0;
2633
2634 /* - stdin */
2635 if (dup2(p_fd[0].rd, 0) == 0)
2636 {
2637 close(p_fd[0].rd);
2638 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2639 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2640 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2641 {
2642 close(p_fd[0].wr);
2643 pipe_err = -1;
2644 }
2645 }
2646 else
2647 {
2648 pipe_err = -1;
2649 }
2650
2651 /* - stdout */
2652 if (pipe_err == 0)
2653 {
2654 if (dup2(p_fd[1].wr, 1) == 1)
2655 {
2656 close(p_fd[1].wr);
2657 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2658 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2659 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2660 {
2661 close(p_fd[1].rd);
2662 pipe_err = -1;
2663 }
2664 }
2665 else
2666 {
2667 pipe_err = -1;
2668 }
2669 }
2670
2671 /* - stderr, as required */
2672 if (pipe_err == 0)
2673 switch (n)
2674 {
2675 case POPEN_3:
2676 {
2677 if (dup2(p_fd[2].wr, 2) == 2)
2678 {
2679 close(p_fd[2].wr);
2680 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2681 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2682 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2683 {
2684 close(p_fd[2].rd);
2685 pipe_err = -1;
2686 }
2687 }
2688 else
2689 {
2690 pipe_err = -1;
2691 }
2692 break;
2693 }
2694
2695 case POPEN_4:
2696 {
2697 if (dup2(1, 2) != 2)
2698 {
2699 pipe_err = -1;
2700 }
2701 break;
2702 }
2703 }
2704
2705 /* spawn the child process */
2706 if (pipe_err == 0)
2707 {
2708 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2709 if (pipe_pid == -1)
2710 {
2711 pipe_err = -1;
2712 }
2713 else
2714 {
2715 /* save the PID into the FILE structure
2716 * NOTE: this implementation doesn't actually
2717 * take advantage of this, but do it for
2718 * completeness - AIM Apr01
2719 */
2720 for (i = 0; i < file_count; i++)
2721 p_s[i]->_pid = pipe_pid;
2722 }
2723 }
2724
2725 /* reset standard IO to normal */
2726 for (i = 0; i < 3; i++)
2727 {
2728 dup2(stdio[i].handle, i);
2729 fcntl(i, F_SETFD, stdio[i].flags);
2730 close(stdio[i].handle);
2731 }
2732
2733 /* if any remnant problems, clean up and bail out */
2734 if (pipe_err < 0)
2735 {
2736 for (i = 0; i < 3; i++)
2737 {
2738 close(p_fd[i].rd);
2739 close(p_fd[i].wr);
2740 }
2741 errno = EPIPE;
2742 return posix_error_with_filename(cmdstring);
2743 }
2744
2745 /* build tuple of file objects to return */
2746 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2747 PyFile_SetBufSize(p_f[0], bufsize);
2748 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2749 PyFile_SetBufSize(p_f[1], bufsize);
2750 if (n == POPEN_3)
2751 {
2752 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2753 PyFile_SetBufSize(p_f[0], bufsize);
2754 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2755 }
2756 else
2757 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2758
2759 /*
2760 * Insert the files we've created into the process dictionary
2761 * all referencing the list with the process handle and the
2762 * initial number of files (see description below in _PyPclose).
2763 * Since if _PyPclose later tried to wait on a process when all
2764 * handles weren't closed, it could create a deadlock with the
2765 * child, we spend some energy here to try to ensure that we
2766 * either insert all file handles into the dictionary or none
2767 * at all. It's a little clumsy with the various popen modes
2768 * and variable number of files involved.
2769 */
2770 if (!_PyPopenProcs)
2771 {
2772 _PyPopenProcs = PyDict_New();
2773 }
2774
2775 if (_PyPopenProcs)
2776 {
2777 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2778 int ins_rc[3];
2779
2780 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2781 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2782
2783 procObj = PyList_New(2);
2784 pidObj = PyInt_FromLong((long) pipe_pid);
2785 intObj = PyInt_FromLong((long) file_count);
2786
2787 if (procObj && pidObj && intObj)
2788 {
2789 PyList_SetItem(procObj, 0, pidObj);
2790 PyList_SetItem(procObj, 1, intObj);
2791
2792 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2793 if (fileObj[0])
2794 {
2795 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2796 fileObj[0],
2797 procObj);
2798 }
2799 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2800 if (fileObj[1])
2801 {
2802 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2803 fileObj[1],
2804 procObj);
2805 }
2806 if (file_count >= 3)
2807 {
2808 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2809 if (fileObj[2])
2810 {
2811 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2812 fileObj[2],
2813 procObj);
2814 }
2815 }
2816
2817 if (ins_rc[0] < 0 || !fileObj[0] ||
2818 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2819 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2820 {
2821 /* Something failed - remove any dictionary
2822 * entries that did make it.
2823 */
2824 if (!ins_rc[0] && fileObj[0])
2825 {
2826 PyDict_DelItem(_PyPopenProcs,
2827 fileObj[0]);
2828 }
2829 if (!ins_rc[1] && fileObj[1])
2830 {
2831 PyDict_DelItem(_PyPopenProcs,
2832 fileObj[1]);
2833 }
2834 if (!ins_rc[2] && fileObj[2])
2835 {
2836 PyDict_DelItem(_PyPopenProcs,
2837 fileObj[2]);
2838 }
2839 }
2840 }
2841
2842 /*
2843 * Clean up our localized references for the dictionary keys
2844 * and value since PyDict_SetItem will Py_INCREF any copies
2845 * that got placed in the dictionary.
2846 */
2847 Py_XDECREF(procObj);
2848 Py_XDECREF(fileObj[0]);
2849 Py_XDECREF(fileObj[1]);
2850 Py_XDECREF(fileObj[2]);
2851 }
2852
2853 /* Child is launched. */
2854 return f;
2855}
2856
2857/*
2858 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2859 * exit code for the child process and return as a result of the close.
2860 *
2861 * This function uses the _PyPopenProcs dictionary in order to map the
2862 * input file pointer to information about the process that was
2863 * originally created by the popen* call that created the file pointer.
2864 * The dictionary uses the file pointer as a key (with one entry
2865 * inserted for each file returned by the original popen* call) and a
2866 * single list object as the value for all files from a single call.
2867 * The list object contains the Win32 process handle at [0], and a file
2868 * count at [1], which is initialized to the total number of file
2869 * handles using that list.
2870 *
2871 * This function closes whichever handle it is passed, and decrements
2872 * the file count in the dictionary for the process handle pointed to
2873 * by this file. On the last close (when the file count reaches zero),
2874 * this function will wait for the child process and then return its
2875 * exit code as the result of the close() operation. This permits the
2876 * files to be closed in any order - it is always the close() of the
2877 * final handle that will return the exit code.
2878 */
2879
2880 /* RED_FLAG 31-Aug-2000 Tim
2881 * This is always called (today!) between a pair of
2882 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2883 * macros. So the thread running this has no valid thread state, as
2884 * far as Python is concerned. However, this calls some Python API
2885 * functions that cannot be called safely without a valid thread
2886 * state, in particular PyDict_GetItem.
2887 * As a temporary hack (although it may last for years ...), we
2888 * *rely* on not having a valid thread state in this function, in
2889 * order to create our own "from scratch".
2890 * This will deadlock if _PyPclose is ever called by a thread
2891 * holding the global lock.
2892 * (The OS/2 EMX thread support appears to cover the case where the
2893 * lock is already held - AIM Apr01)
2894 */
2895
2896static int _PyPclose(FILE *file)
2897{
2898 int result;
2899 int exit_code;
2900 int pipe_pid;
2901 PyObject *procObj, *pidObj, *intObj, *fileObj;
2902 int file_count;
2903#ifdef WITH_THREAD
2904 PyInterpreterState* pInterpreterState;
2905 PyThreadState* pThreadState;
2906#endif
2907
2908 /* Close the file handle first, to ensure it can't block the
2909 * child from exiting if it's the last handle.
2910 */
2911 result = fclose(file);
2912
2913#ifdef WITH_THREAD
2914 /* Bootstrap a valid thread state into existence. */
2915 pInterpreterState = PyInterpreterState_New();
2916 if (!pInterpreterState) {
2917 /* Well, we're hosed now! We don't have a thread
2918 * state, so can't call a nice error routine, or raise
2919 * an exception. Just die.
2920 */
2921 Py_FatalError("unable to allocate interpreter state "
2922 "when closing popen object.");
2923 return -1; /* unreachable */
2924 }
2925 pThreadState = PyThreadState_New(pInterpreterState);
2926 if (!pThreadState) {
2927 Py_FatalError("unable to allocate thread state "
2928 "when closing popen object.");
2929 return -1; /* unreachable */
2930 }
2931 /* Grab the global lock. Note that this will deadlock if the
2932 * current thread already has the lock! (see RED_FLAG comments
2933 * before this function)
2934 */
2935 PyEval_RestoreThread(pThreadState);
2936#endif
2937
2938 if (_PyPopenProcs)
2939 {
2940 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2941 (procObj = PyDict_GetItem(_PyPopenProcs,
2942 fileObj)) != NULL &&
2943 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2944 (intObj = PyList_GetItem(procObj,1)) != NULL)
2945 {
2946 pipe_pid = (int) PyInt_AsLong(pidObj);
2947 file_count = (int) PyInt_AsLong(intObj);
2948
2949 if (file_count > 1)
2950 {
2951 /* Still other files referencing process */
2952 file_count--;
2953 PyList_SetItem(procObj,1,
2954 PyInt_FromLong((long) file_count));
2955 }
2956 else
2957 {
2958 /* Last file for this process */
2959 if (result != EOF &&
2960 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2961 {
2962 /* extract exit status */
2963 if (WIFEXITED(exit_code))
2964 {
2965 result = WEXITSTATUS(exit_code);
2966 }
2967 else
2968 {
2969 errno = EPIPE;
2970 result = -1;
2971 }
2972 }
2973 else
2974 {
2975 /* Indicate failure - this will cause the file object
2976 * to raise an I/O error and translate the last
2977 * error code from errno. We do have a problem with
2978 * last errors that overlap the normal errno table,
2979 * but that's a consistent problem with the file object.
2980 */
2981 result = -1;
2982 }
2983 }
2984
2985 /* Remove this file pointer from dictionary */
2986 PyDict_DelItem(_PyPopenProcs, fileObj);
2987
2988 if (PyDict_Size(_PyPopenProcs) == 0)
2989 {
2990 Py_DECREF(_PyPopenProcs);
2991 _PyPopenProcs = NULL;
2992 }
2993
2994 } /* if object retrieval ok */
2995
2996 Py_XDECREF(fileObj);
2997 } /* if _PyPopenProcs */
2998
2999#ifdef WITH_THREAD
3000 /* Tear down the thread & interpreter states.
3001 * Note that interpreter state clear & delete functions automatically
3002 * call the thread clear & delete functions, and indeed insist on
3003 * doing that themselves. The lock must be held during the clear, but
3004 * need not be held during the delete.
3005 */
3006 PyInterpreterState_Clear(pInterpreterState);
3007 PyEval_ReleaseThread(pThreadState);
3008 PyInterpreterState_Delete(pInterpreterState);
3009#endif
3010
3011 return result;
3012}
3013
3014#endif /* PYCC_??? */
3015
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003016#elif defined(MS_WIN32)
3017
3018/*
3019 * Portable 'popen' replacement for Win32.
3020 *
3021 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3022 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003023 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003024 */
3025
3026#include <malloc.h>
3027#include <io.h>
3028#include <fcntl.h>
3029
3030/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3031#define POPEN_1 1
3032#define POPEN_2 2
3033#define POPEN_3 3
3034#define POPEN_4 4
3035
3036static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003037static int _PyPclose(FILE *file);
3038
3039/*
3040 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003041 * for use when retrieving the process exit code. See _PyPclose() below
3042 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003043 */
3044static PyObject *_PyPopenProcs = NULL;
3045
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003046
3047/* popen that works from a GUI.
3048 *
3049 * The result of this function is a pipe (file) connected to the
3050 * processes stdin or stdout, depending on the requested mode.
3051 */
3052
3053static PyObject *
3054posix_popen(PyObject *self, PyObject *args)
3055{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003056 PyObject *f, *s;
3057 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003058
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003059 char *cmdstring;
3060 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003061 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003062 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003063 return NULL;
3064
3065 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003066
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003067 if (*mode == 'r')
3068 tm = _O_RDONLY;
3069 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003070 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003071 return NULL;
3072 } else
3073 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003074
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003075 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003076 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003077 return NULL;
3078 }
3079
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003080 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003081 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003082 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003083 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003084 else
3085 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3086
3087 return f;
3088}
3089
3090/* Variation on win32pipe.popen
3091 *
3092 * The result of this function is a pipe (file) connected to the
3093 * process's stdin, and a pipe connected to the process's stdout.
3094 */
3095
3096static PyObject *
3097win32_popen2(PyObject *self, PyObject *args)
3098{
3099 PyObject *f;
3100 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003101
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003102 char *cmdstring;
3103 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003104 int bufsize = -1;
3105 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003106 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003107
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003108 if (*mode == 't')
3109 tm = _O_TEXT;
3110 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003111 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003112 return NULL;
3113 } else
3114 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003115
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003116 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003117 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003118 return NULL;
3119 }
3120
3121 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003122
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003123 return f;
3124}
3125
3126/*
3127 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003128 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003129 * The result of this function is 3 pipes - the process's stdin,
3130 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003131 */
3132
3133static PyObject *
3134win32_popen3(PyObject *self, PyObject *args)
3135{
3136 PyObject *f;
3137 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003138
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003139 char *cmdstring;
3140 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003141 int bufsize = -1;
3142 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003143 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003144
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003145 if (*mode == 't')
3146 tm = _O_TEXT;
3147 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003148 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003149 return NULL;
3150 } else
3151 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003152
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003153 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003154 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003155 return NULL;
3156 }
3157
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003158 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003159
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003160 return f;
3161}
3162
3163/*
3164 * Variation on win32pipe.popen
3165 *
Tim Peters5aa91602002-01-30 05:46:57 +00003166 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003167 * and stdout+stderr combined as a single pipe.
3168 */
3169
3170static PyObject *
3171win32_popen4(PyObject *self, PyObject *args)
3172{
3173 PyObject *f;
3174 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003175
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003176 char *cmdstring;
3177 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003178 int bufsize = -1;
3179 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003180 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003181
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003182 if (*mode == 't')
3183 tm = _O_TEXT;
3184 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003185 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003186 return NULL;
3187 } else
3188 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003189
3190 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003191 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003192 return NULL;
3193 }
3194
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003195 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003196
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003197 return f;
3198}
3199
Mark Hammond08501372001-01-31 07:30:29 +00003200static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003201_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003202 HANDLE hStdin,
3203 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003204 HANDLE hStderr,
3205 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003206{
3207 PROCESS_INFORMATION piProcInfo;
3208 STARTUPINFO siStartInfo;
3209 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003210 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003211 int i;
3212 int x;
3213
3214 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003215 char *comshell;
3216
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003217 s1 = (char *)_alloca(i);
3218 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3219 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003220
3221 /* Explicitly check if we are using COMMAND.COM. If we are
3222 * then use the w9xpopen hack.
3223 */
3224 comshell = s1 + x;
3225 while (comshell >= s1 && *comshell != '\\')
3226 --comshell;
3227 ++comshell;
3228
3229 if (GetVersion() < 0x80000000 &&
3230 _stricmp(comshell, "command.com") != 0) {
3231 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003232 x = i + strlen(s3) + strlen(cmdstring) + 1;
3233 s2 = (char *)_alloca(x);
3234 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003235 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003236 }
3237 else {
3238 /*
Tim Peters402d5982001-08-27 06:37:48 +00003239 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3240 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003241 */
Mark Hammond08501372001-01-31 07:30:29 +00003242 char modulepath[_MAX_PATH];
3243 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003244 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3245 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003246 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003247 x = i+1;
3248 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003249 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003250 strncat(modulepath,
3251 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003252 (sizeof(modulepath)/sizeof(modulepath[0]))
3253 -strlen(modulepath));
3254 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003255 /* Eeek - file-not-found - possibly an embedding
3256 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003257 */
Tim Peters5aa91602002-01-30 05:46:57 +00003258 strncpy(modulepath,
3259 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003260 sizeof(modulepath)/sizeof(modulepath[0]));
3261 if (modulepath[strlen(modulepath)-1] != '\\')
3262 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003263 strncat(modulepath,
3264 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003265 (sizeof(modulepath)/sizeof(modulepath[0]))
3266 -strlen(modulepath));
3267 /* No where else to look - raise an easily identifiable
3268 error, rather than leaving Windows to report
3269 "file not found" - as the user is probably blissfully
3270 unaware this shim EXE is used, and it will confuse them.
3271 (well, it confused me for a while ;-)
3272 */
3273 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003274 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003275 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003276 "for popen to work with your shell "
3277 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003278 szConsoleSpawn);
3279 return FALSE;
3280 }
3281 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003282 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003283 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003284 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003285
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003286 s2 = (char *)_alloca(x);
3287 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003288 /* To maintain correct argument passing semantics,
3289 we pass the command-line as it stands, and allow
3290 quoting to be applied. w9xpopen.exe will then
3291 use its argv vector, and re-quote the necessary
3292 args for the ultimate child process.
3293 */
Tim Peters75cdad52001-11-28 22:07:30 +00003294 PyOS_snprintf(
3295 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003296 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003297 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003298 s1,
3299 s3,
3300 cmdstring);
3301 }
3302 }
3303
3304 /* Could be an else here to try cmd.exe / command.com in the path
3305 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003306 else {
Tim Peters402d5982001-08-27 06:37:48 +00003307 PyErr_SetString(PyExc_RuntimeError,
3308 "Cannot locate a COMSPEC environment variable to "
3309 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003310 return FALSE;
3311 }
Tim Peters5aa91602002-01-30 05:46:57 +00003312
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003313 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3314 siStartInfo.cb = sizeof(STARTUPINFO);
3315 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3316 siStartInfo.hStdInput = hStdin;
3317 siStartInfo.hStdOutput = hStdout;
3318 siStartInfo.hStdError = hStderr;
3319 siStartInfo.wShowWindow = SW_HIDE;
3320
3321 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003322 s2,
3323 NULL,
3324 NULL,
3325 TRUE,
3326 CREATE_NEW_CONSOLE,
3327 NULL,
3328 NULL,
3329 &siStartInfo,
3330 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003331 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003332 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003333
Mark Hammondb37a3732000-08-14 04:47:33 +00003334 /* Return process handle */
3335 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003336 return TRUE;
3337 }
Tim Peters402d5982001-08-27 06:37:48 +00003338 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003339 return FALSE;
3340}
3341
3342/* The following code is based off of KB: Q190351 */
3343
3344static PyObject *
3345_PyPopen(char *cmdstring, int mode, int n)
3346{
3347 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3348 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003349 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003350
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003351 SECURITY_ATTRIBUTES saAttr;
3352 BOOL fSuccess;
3353 int fd1, fd2, fd3;
3354 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003355 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003356 PyObject *f;
3357
3358 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3359 saAttr.bInheritHandle = TRUE;
3360 saAttr.lpSecurityDescriptor = NULL;
3361
3362 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3363 return win32_error("CreatePipe", NULL);
3364
3365 /* Create new output read handle and the input write handle. Set
3366 * the inheritance properties to FALSE. Otherwise, the child inherits
3367 * the these handles; resulting in non-closeable handles to the pipes
3368 * being created. */
3369 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003370 GetCurrentProcess(), &hChildStdinWrDup, 0,
3371 FALSE,
3372 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003373 if (!fSuccess)
3374 return win32_error("DuplicateHandle", NULL);
3375
3376 /* Close the inheritable version of ChildStdin
3377 that we're using. */
3378 CloseHandle(hChildStdinWr);
3379
3380 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3381 return win32_error("CreatePipe", NULL);
3382
3383 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003384 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3385 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003386 if (!fSuccess)
3387 return win32_error("DuplicateHandle", NULL);
3388
3389 /* Close the inheritable version of ChildStdout
3390 that we're using. */
3391 CloseHandle(hChildStdoutRd);
3392
3393 if (n != POPEN_4) {
3394 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3395 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003396 fSuccess = DuplicateHandle(GetCurrentProcess(),
3397 hChildStderrRd,
3398 GetCurrentProcess(),
3399 &hChildStderrRdDup, 0,
3400 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003401 if (!fSuccess)
3402 return win32_error("DuplicateHandle", NULL);
3403 /* Close the inheritable version of ChildStdErr that we're using. */
3404 CloseHandle(hChildStderrRd);
3405 }
Tim Peters5aa91602002-01-30 05:46:57 +00003406
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003407 switch (n) {
3408 case POPEN_1:
3409 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3410 case _O_WRONLY | _O_TEXT:
3411 /* Case for writing to child Stdin in text mode. */
3412 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3413 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003414 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003415 PyFile_SetBufSize(f, 0);
3416 /* We don't care about these pipes anymore, so close them. */
3417 CloseHandle(hChildStdoutRdDup);
3418 CloseHandle(hChildStderrRdDup);
3419 break;
3420
3421 case _O_RDONLY | _O_TEXT:
3422 /* Case for reading from child Stdout in text mode. */
3423 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3424 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003425 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003426 PyFile_SetBufSize(f, 0);
3427 /* We don't care about these pipes anymore, so close them. */
3428 CloseHandle(hChildStdinWrDup);
3429 CloseHandle(hChildStderrRdDup);
3430 break;
3431
3432 case _O_RDONLY | _O_BINARY:
3433 /* Case for readinig from child Stdout in binary mode. */
3434 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3435 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003436 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003437 PyFile_SetBufSize(f, 0);
3438 /* We don't care about these pipes anymore, so close them. */
3439 CloseHandle(hChildStdinWrDup);
3440 CloseHandle(hChildStderrRdDup);
3441 break;
3442
3443 case _O_WRONLY | _O_BINARY:
3444 /* Case for writing to child Stdin in binary mode. */
3445 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3446 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003447 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003448 PyFile_SetBufSize(f, 0);
3449 /* We don't care about these pipes anymore, so close them. */
3450 CloseHandle(hChildStdoutRdDup);
3451 CloseHandle(hChildStderrRdDup);
3452 break;
3453 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003454 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003455 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003456
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003457 case POPEN_2:
3458 case POPEN_4:
3459 {
3460 char *m1, *m2;
3461 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003462
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003463 if (mode && _O_TEXT) {
3464 m1 = "r";
3465 m2 = "w";
3466 } else {
3467 m1 = "rb";
3468 m2 = "wb";
3469 }
3470
3471 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3472 f1 = _fdopen(fd1, m2);
3473 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3474 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003475 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003476 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003477 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003478 PyFile_SetBufSize(p2, 0);
3479
3480 if (n != 4)
3481 CloseHandle(hChildStderrRdDup);
3482
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003483 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003484 Py_XDECREF(p1);
3485 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003486 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003487 break;
3488 }
Tim Peters5aa91602002-01-30 05:46:57 +00003489
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003490 case POPEN_3:
3491 {
3492 char *m1, *m2;
3493 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003494
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003495 if (mode && _O_TEXT) {
3496 m1 = "r";
3497 m2 = "w";
3498 } else {
3499 m1 = "rb";
3500 m2 = "wb";
3501 }
3502
3503 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3504 f1 = _fdopen(fd1, m2);
3505 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3506 f2 = _fdopen(fd2, m1);
3507 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3508 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003509 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003510 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3511 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003512 PyFile_SetBufSize(p1, 0);
3513 PyFile_SetBufSize(p2, 0);
3514 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003515 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003516 Py_XDECREF(p1);
3517 Py_XDECREF(p2);
3518 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003519 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003520 break;
3521 }
3522 }
3523
3524 if (n == POPEN_4) {
3525 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003526 hChildStdinRd,
3527 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003528 hChildStdoutWr,
3529 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003530 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003531 }
3532 else {
3533 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003534 hChildStdinRd,
3535 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003536 hChildStderrWr,
3537 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003538 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003539 }
3540
Mark Hammondb37a3732000-08-14 04:47:33 +00003541 /*
3542 * Insert the files we've created into the process dictionary
3543 * all referencing the list with the process handle and the
3544 * initial number of files (see description below in _PyPclose).
3545 * Since if _PyPclose later tried to wait on a process when all
3546 * handles weren't closed, it could create a deadlock with the
3547 * child, we spend some energy here to try to ensure that we
3548 * either insert all file handles into the dictionary or none
3549 * at all. It's a little clumsy with the various popen modes
3550 * and variable number of files involved.
3551 */
3552 if (!_PyPopenProcs) {
3553 _PyPopenProcs = PyDict_New();
3554 }
3555
3556 if (_PyPopenProcs) {
3557 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3558 int ins_rc[3];
3559
3560 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3561 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3562
3563 procObj = PyList_New(2);
3564 hProcessObj = PyLong_FromVoidPtr(hProcess);
3565 intObj = PyInt_FromLong(file_count);
3566
3567 if (procObj && hProcessObj && intObj) {
3568 PyList_SetItem(procObj,0,hProcessObj);
3569 PyList_SetItem(procObj,1,intObj);
3570
3571 fileObj[0] = PyLong_FromVoidPtr(f1);
3572 if (fileObj[0]) {
3573 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3574 fileObj[0],
3575 procObj);
3576 }
3577 if (file_count >= 2) {
3578 fileObj[1] = PyLong_FromVoidPtr(f2);
3579 if (fileObj[1]) {
3580 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3581 fileObj[1],
3582 procObj);
3583 }
3584 }
3585 if (file_count >= 3) {
3586 fileObj[2] = PyLong_FromVoidPtr(f3);
3587 if (fileObj[2]) {
3588 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3589 fileObj[2],
3590 procObj);
3591 }
3592 }
3593
3594 if (ins_rc[0] < 0 || !fileObj[0] ||
3595 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3596 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3597 /* Something failed - remove any dictionary
3598 * entries that did make it.
3599 */
3600 if (!ins_rc[0] && fileObj[0]) {
3601 PyDict_DelItem(_PyPopenProcs,
3602 fileObj[0]);
3603 }
3604 if (!ins_rc[1] && fileObj[1]) {
3605 PyDict_DelItem(_PyPopenProcs,
3606 fileObj[1]);
3607 }
3608 if (!ins_rc[2] && fileObj[2]) {
3609 PyDict_DelItem(_PyPopenProcs,
3610 fileObj[2]);
3611 }
3612 }
3613 }
Tim Peters5aa91602002-01-30 05:46:57 +00003614
Mark Hammondb37a3732000-08-14 04:47:33 +00003615 /*
3616 * Clean up our localized references for the dictionary keys
3617 * and value since PyDict_SetItem will Py_INCREF any copies
3618 * that got placed in the dictionary.
3619 */
3620 Py_XDECREF(procObj);
3621 Py_XDECREF(fileObj[0]);
3622 Py_XDECREF(fileObj[1]);
3623 Py_XDECREF(fileObj[2]);
3624 }
3625
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003626 /* Child is launched. Close the parents copy of those pipe
3627 * handles that only the child should have open. You need to
3628 * make sure that no handles to the write end of the output pipe
3629 * are maintained in this process or else the pipe will not close
3630 * when the child process exits and the ReadFile will hang. */
3631
3632 if (!CloseHandle(hChildStdinRd))
3633 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003634
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003635 if (!CloseHandle(hChildStdoutWr))
3636 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003637
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003638 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3639 return win32_error("CloseHandle", NULL);
3640
3641 return f;
3642}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003643
3644/*
3645 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3646 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003647 *
3648 * This function uses the _PyPopenProcs dictionary in order to map the
3649 * input file pointer to information about the process that was
3650 * originally created by the popen* call that created the file pointer.
3651 * The dictionary uses the file pointer as a key (with one entry
3652 * inserted for each file returned by the original popen* call) and a
3653 * single list object as the value for all files from a single call.
3654 * The list object contains the Win32 process handle at [0], and a file
3655 * count at [1], which is initialized to the total number of file
3656 * handles using that list.
3657 *
3658 * This function closes whichever handle it is passed, and decrements
3659 * the file count in the dictionary for the process handle pointed to
3660 * by this file. On the last close (when the file count reaches zero),
3661 * this function will wait for the child process and then return its
3662 * exit code as the result of the close() operation. This permits the
3663 * files to be closed in any order - it is always the close() of the
3664 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003665 */
Tim Peters736aa322000-09-01 06:51:24 +00003666
3667 /* RED_FLAG 31-Aug-2000 Tim
3668 * This is always called (today!) between a pair of
3669 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3670 * macros. So the thread running this has no valid thread state, as
3671 * far as Python is concerned. However, this calls some Python API
3672 * functions that cannot be called safely without a valid thread
3673 * state, in particular PyDict_GetItem.
3674 * As a temporary hack (although it may last for years ...), we
3675 * *rely* on not having a valid thread state in this function, in
3676 * order to create our own "from scratch".
3677 * This will deadlock if _PyPclose is ever called by a thread
3678 * holding the global lock.
3679 */
3680
Fredrik Lundh56055a42000-07-23 19:47:12 +00003681static int _PyPclose(FILE *file)
3682{
Fredrik Lundh20318932000-07-26 17:29:12 +00003683 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003684 DWORD exit_code;
3685 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003686 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3687 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003688#ifdef WITH_THREAD
3689 PyInterpreterState* pInterpreterState;
3690 PyThreadState* pThreadState;
3691#endif
3692
Fredrik Lundh20318932000-07-26 17:29:12 +00003693 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003694 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003695 */
3696 result = fclose(file);
3697
Tim Peters736aa322000-09-01 06:51:24 +00003698#ifdef WITH_THREAD
3699 /* Bootstrap a valid thread state into existence. */
3700 pInterpreterState = PyInterpreterState_New();
3701 if (!pInterpreterState) {
3702 /* Well, we're hosed now! We don't have a thread
3703 * state, so can't call a nice error routine, or raise
3704 * an exception. Just die.
3705 */
3706 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003707 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003708 return -1; /* unreachable */
3709 }
3710 pThreadState = PyThreadState_New(pInterpreterState);
3711 if (!pThreadState) {
3712 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003713 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003714 return -1; /* unreachable */
3715 }
3716 /* Grab the global lock. Note that this will deadlock if the
3717 * current thread already has the lock! (see RED_FLAG comments
3718 * before this function)
3719 */
3720 PyEval_RestoreThread(pThreadState);
3721#endif
3722
Fredrik Lundh56055a42000-07-23 19:47:12 +00003723 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003724 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3725 (procObj = PyDict_GetItem(_PyPopenProcs,
3726 fileObj)) != NULL &&
3727 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3728 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3729
3730 hProcess = PyLong_AsVoidPtr(hProcessObj);
3731 file_count = PyInt_AsLong(intObj);
3732
3733 if (file_count > 1) {
3734 /* Still other files referencing process */
3735 file_count--;
3736 PyList_SetItem(procObj,1,
3737 PyInt_FromLong(file_count));
3738 } else {
3739 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003740 if (result != EOF &&
3741 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3742 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003743 /* Possible truncation here in 16-bit environments, but
3744 * real exit codes are just the lower byte in any event.
3745 */
3746 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003747 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003748 /* Indicate failure - this will cause the file object
3749 * to raise an I/O error and translate the last Win32
3750 * error code from errno. We do have a problem with
3751 * last errors that overlap the normal errno table,
3752 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003753 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003754 if (result != EOF) {
3755 /* If the error wasn't from the fclose(), then
3756 * set errno for the file object error handling.
3757 */
3758 errno = GetLastError();
3759 }
3760 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003761 }
3762
3763 /* Free up the native handle at this point */
3764 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003765 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003766
Mark Hammondb37a3732000-08-14 04:47:33 +00003767 /* Remove this file pointer from dictionary */
3768 PyDict_DelItem(_PyPopenProcs, fileObj);
3769
3770 if (PyDict_Size(_PyPopenProcs) == 0) {
3771 Py_DECREF(_PyPopenProcs);
3772 _PyPopenProcs = NULL;
3773 }
3774
3775 } /* if object retrieval ok */
3776
3777 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003778 } /* if _PyPopenProcs */
3779
Tim Peters736aa322000-09-01 06:51:24 +00003780#ifdef WITH_THREAD
3781 /* Tear down the thread & interpreter states.
3782 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003783 * call the thread clear & delete functions, and indeed insist on
3784 * doing that themselves. The lock must be held during the clear, but
3785 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003786 */
3787 PyInterpreterState_Clear(pInterpreterState);
3788 PyEval_ReleaseThread(pThreadState);
3789 PyInterpreterState_Delete(pInterpreterState);
3790#endif
3791
Fredrik Lundh56055a42000-07-23 19:47:12 +00003792 return result;
3793}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003794
3795#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003796static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003797posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003798{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003799 char *name;
3800 char *mode = "r";
3801 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003802 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003803 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003804 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003805 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003806 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003807 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003808 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003809 if (fp == NULL)
3810 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003811 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003812 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003813 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003814 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003815}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003816
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003817#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003818#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003819
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003820
Guido van Rossumb6775db1994-08-01 11:34:53 +00003821#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003822static char posix_setuid__doc__[] =
3823"setuid(uid) -> None\n\
3824Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003826posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003827{
3828 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003829 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003830 return NULL;
3831 if (setuid(uid) < 0)
3832 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003833 Py_INCREF(Py_None);
3834 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003835}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003836#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003838
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003839#ifdef HAVE_SETEUID
3840static char posix_seteuid__doc__[] =
3841"seteuid(uid) -> None\n\
3842Set the current process's effective user id.";
3843static PyObject *
3844posix_seteuid (PyObject *self, PyObject *args)
3845{
3846 int euid;
3847 if (!PyArg_ParseTuple(args, "i", &euid)) {
3848 return NULL;
3849 } else if (seteuid(euid) < 0) {
3850 return posix_error();
3851 } else {
3852 Py_INCREF(Py_None);
3853 return Py_None;
3854 }
3855}
3856#endif /* HAVE_SETEUID */
3857
3858#ifdef HAVE_SETEGID
3859static char posix_setegid__doc__[] =
3860"setegid(gid) -> None\n\
3861Set the current process's effective group id.";
3862static PyObject *
3863posix_setegid (PyObject *self, PyObject *args)
3864{
3865 int egid;
3866 if (!PyArg_ParseTuple(args, "i", &egid)) {
3867 return NULL;
3868 } else if (setegid(egid) < 0) {
3869 return posix_error();
3870 } else {
3871 Py_INCREF(Py_None);
3872 return Py_None;
3873 }
3874}
3875#endif /* HAVE_SETEGID */
3876
3877#ifdef HAVE_SETREUID
3878static char posix_setreuid__doc__[] =
3879"seteuid(ruid, euid) -> None\n\
3880Set the current process's real and effective user ids.";
3881static PyObject *
3882posix_setreuid (PyObject *self, PyObject *args)
3883{
3884 int ruid, euid;
3885 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3886 return NULL;
3887 } else if (setreuid(ruid, euid) < 0) {
3888 return posix_error();
3889 } else {
3890 Py_INCREF(Py_None);
3891 return Py_None;
3892 }
3893}
3894#endif /* HAVE_SETREUID */
3895
3896#ifdef HAVE_SETREGID
3897static char posix_setregid__doc__[] =
3898"setegid(rgid, egid) -> None\n\
3899Set the current process's real and effective group ids.";
3900static PyObject *
3901posix_setregid (PyObject *self, PyObject *args)
3902{
3903 int rgid, egid;
3904 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3905 return NULL;
3906 } else if (setregid(rgid, egid) < 0) {
3907 return posix_error();
3908 } else {
3909 Py_INCREF(Py_None);
3910 return Py_None;
3911 }
3912}
3913#endif /* HAVE_SETREGID */
3914
Guido van Rossumb6775db1994-08-01 11:34:53 +00003915#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003916static char posix_setgid__doc__[] =
3917"setgid(gid) -> None\n\
3918Set the current process's group id.";
3919
Barry Warsaw53699e91996-12-10 23:23:01 +00003920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003921posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003922{
3923 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003924 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003925 return NULL;
3926 if (setgid(gid) < 0)
3927 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003928 Py_INCREF(Py_None);
3929 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003930}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003931#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003932
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003933#ifdef HAVE_SETGROUPS
3934static char posix_setgroups__doc__[] =
3935"setgroups(list) -> None\n\
3936Set the groups of the current process to list.";
3937
3938static PyObject *
3939posix_setgroups(PyObject *self, PyObject *args)
3940{
3941 PyObject *groups;
3942 int i, len;
3943 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003944
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003945 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3946 return NULL;
3947 if (!PySequence_Check(groups)) {
3948 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3949 return NULL;
3950 }
3951 len = PySequence_Size(groups);
3952 if (len > MAX_GROUPS) {
3953 PyErr_SetString(PyExc_ValueError, "too many groups");
3954 return NULL;
3955 }
3956 for(i = 0; i < len; i++) {
3957 PyObject *elem;
3958 elem = PySequence_GetItem(groups, i);
3959 if (!elem)
3960 return NULL;
3961 if (!PyInt_Check(elem)) {
3962 PyErr_SetString(PyExc_TypeError,
3963 "groups must be integers");
3964 Py_DECREF(elem);
3965 return NULL;
3966 }
3967 /* XXX: check that value fits into gid_t. */
3968 grouplist[i] = PyInt_AsLong(elem);
3969 Py_DECREF(elem);
3970 }
3971
3972 if (setgroups(len, grouplist) < 0)
3973 return posix_error();
3974 Py_INCREF(Py_None);
3975 return Py_None;
3976}
3977#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003978
Guido van Rossumb6775db1994-08-01 11:34:53 +00003979#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003980static char posix_waitpid__doc__[] =
3981"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003982Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003983
Barry Warsaw53699e91996-12-10 23:23:01 +00003984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003985posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003986{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003987 int pid, options;
3988#ifdef UNION_WAIT
3989 union wait status;
3990#define status_i (status.w_status)
3991#else
3992 int status;
3993#define status_i status
3994#endif
3995 status_i = 0;
3996
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003997 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003998 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003999 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004000 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004001 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004002 if (pid == -1)
4003 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004004 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004005 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004006}
4007
Tim Petersab034fa2002-02-01 11:27:43 +00004008#elif defined(HAVE_CWAIT)
4009
4010/* MS C has a variant of waitpid() that's usable for most purposes. */
4011static char posix_waitpid__doc__[] =
4012"waitpid(pid, options) -> (pid, status << 8)\n"
4013"Wait for completion of a given process. options is ignored on Windows.";
4014
4015static PyObject *
4016posix_waitpid(PyObject *self, PyObject *args)
4017{
4018 int pid, options;
4019 int status;
4020
4021 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4022 return NULL;
4023 Py_BEGIN_ALLOW_THREADS
4024 pid = _cwait(&status, pid, options);
4025 Py_END_ALLOW_THREADS
4026 if (pid == -1)
4027 return posix_error();
4028 else
4029 /* shift the status left a byte so this is more like the
4030 POSIX waitpid */
4031 return Py_BuildValue("ii", pid, status << 8);
4032}
4033#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004034
Guido van Rossumad0ee831995-03-01 10:34:45 +00004035#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004036static char posix_wait__doc__[] =
4037"wait() -> (pid, status)\n\
4038Wait for completion of a child process.";
4039
Barry Warsaw53699e91996-12-10 23:23:01 +00004040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004041posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004042{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004043 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004044#ifdef UNION_WAIT
4045 union wait status;
4046#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004047#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004048 int status;
4049#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004050#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004051 if (!PyArg_ParseTuple(args, ":wait"))
4052 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004053 status_i = 0;
4054 Py_BEGIN_ALLOW_THREADS
4055 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004056 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004057 if (pid == -1)
4058 return posix_error();
4059 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004060 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004061#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004062}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004063#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004065
4066static char posix_lstat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00004067"lstat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
4068 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004069Like stat(path), but do not follow symbolic links.";
4070
Barry Warsaw53699e91996-12-10 23:23:01 +00004071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004072posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004073{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004074#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004075 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004076#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004077 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004078#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004079}
4080
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004081
Guido van Rossumb6775db1994-08-01 11:34:53 +00004082#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004083static char posix_readlink__doc__[] =
4084"readlink(path) -> path\n\
4085Return a string representing the path to which the symbolic link points.";
4086
Barry Warsaw53699e91996-12-10 23:23:01 +00004087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004088posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004089{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004090 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004091 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004092 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004093 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004094 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004095 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004096 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004097 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004098 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004099 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004100 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004101}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004102#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004103
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004104
Guido van Rossumb6775db1994-08-01 11:34:53 +00004105#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004106static char posix_symlink__doc__[] =
4107"symlink(src, dst) -> None\n\
4108Create a symbolic link.";
4109
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004111posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004112{
Mark Hammondef8b6542001-05-13 08:04:26 +00004113 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004114}
4115#endif /* HAVE_SYMLINK */
4116
4117
4118#ifdef HAVE_TIMES
4119#ifndef HZ
4120#define HZ 60 /* Universal constant :-) */
4121#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004122
Guido van Rossumd48f2521997-12-05 22:19:34 +00004123#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4124static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004125system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004126{
4127 ULONG value = 0;
4128
4129 Py_BEGIN_ALLOW_THREADS
4130 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4131 Py_END_ALLOW_THREADS
4132
4133 return value;
4134}
4135
4136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004137posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004138{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004139 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004140 return NULL;
4141
4142 /* Currently Only Uptime is Provided -- Others Later */
4143 return Py_BuildValue("ddddd",
4144 (double)0 /* t.tms_utime / HZ */,
4145 (double)0 /* t.tms_stime / HZ */,
4146 (double)0 /* t.tms_cutime / HZ */,
4147 (double)0 /* t.tms_cstime / HZ */,
4148 (double)system_uptime() / 1000);
4149}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004150#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004152posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004153{
4154 struct tms t;
4155 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004156 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004157 return NULL;
4158 errno = 0;
4159 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004160 if (c == (clock_t) -1)
4161 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004162 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004163 (double)t.tms_utime / HZ,
4164 (double)t.tms_stime / HZ,
4165 (double)t.tms_cutime / HZ,
4166 (double)t.tms_cstime / HZ,
4167 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004168}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004169#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004170#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004171
4172
Guido van Rossum87755a21996-09-07 00:59:43 +00004173#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004174#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004176posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004177{
4178 FILETIME create, exit, kernel, user;
4179 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004180 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004181 return NULL;
4182 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004183 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4184 /* The fields of a FILETIME structure are the hi and lo part
4185 of a 64-bit value expressed in 100 nanosecond units.
4186 1e7 is one second in such units; 1e-7 the inverse.
4187 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4188 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004189 return Py_BuildValue(
4190 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004191 (double)(kernel.dwHighDateTime*429.4967296 +
4192 kernel.dwLowDateTime*1e-7),
4193 (double)(user.dwHighDateTime*429.4967296 +
4194 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004195 (double)0,
4196 (double)0,
4197 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004198}
Guido van Rossum8d665e61996-06-26 18:22:49 +00004199#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004200
4201#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00004202static char posix_times__doc__[] =
4203"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
4204Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004205#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004207
Guido van Rossumb6775db1994-08-01 11:34:53 +00004208#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004209static char posix_setsid__doc__[] =
4210"setsid() -> None\n\
4211Call the system call setsid().";
4212
Barry Warsaw53699e91996-12-10 23:23:01 +00004213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004214posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004215{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004216 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004217 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004218 if (setsid() < 0)
4219 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004220 Py_INCREF(Py_None);
4221 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004222}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004223#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004224
Guido van Rossumb6775db1994-08-01 11:34:53 +00004225#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004226static char posix_setpgid__doc__[] =
4227"setpgid(pid, pgrp) -> None\n\
4228Call the system call setpgid().";
4229
Barry Warsaw53699e91996-12-10 23:23:01 +00004230static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004231posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004232{
4233 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004234 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004235 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004236 if (setpgid(pid, pgrp) < 0)
4237 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004238 Py_INCREF(Py_None);
4239 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004240}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004241#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004243
Guido van Rossumb6775db1994-08-01 11:34:53 +00004244#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004245static char posix_tcgetpgrp__doc__[] =
4246"tcgetpgrp(fd) -> pgid\n\
4247Return the process group associated with the terminal given by a fd.";
4248
Barry Warsaw53699e91996-12-10 23:23:01 +00004249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004250posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004251{
4252 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004253 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004254 return NULL;
4255 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004256 if (pgid < 0)
4257 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004258 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004259}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004260#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004262
Guido van Rossumb6775db1994-08-01 11:34:53 +00004263#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004264static char posix_tcsetpgrp__doc__[] =
4265"tcsetpgrp(fd, pgid) -> None\n\
4266Set the process group associated with the terminal given by a fd.";
4267
Barry Warsaw53699e91996-12-10 23:23:01 +00004268static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004269posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004270{
4271 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004272 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004273 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004274 if (tcsetpgrp(fd, pgid) < 0)
4275 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004276 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004277 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004278}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004279#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004280
Guido van Rossum687dd131993-05-17 08:34:16 +00004281/* Functions acting on file descriptors */
4282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283static char posix_open__doc__[] =
4284"open(filename, flag [, mode=0777]) -> fd\n\
4285Open a file (for low level IO).";
4286
Barry Warsaw53699e91996-12-10 23:23:01 +00004287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004288posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004289{
Mark Hammondef8b6542001-05-13 08:04:26 +00004290 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004291 int flag;
4292 int mode = 0777;
4293 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004294 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004295 Py_FileSystemDefaultEncoding, &file,
4296 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004297 return NULL;
4298
Barry Warsaw53699e91996-12-10 23:23:01 +00004299 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004300 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004301 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004302 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004303 return posix_error_with_allocated_filename(file);
4304 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004305 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004306}
4307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004308
4309static char posix_close__doc__[] =
4310"close(fd) -> None\n\
4311Close a file descriptor (for low level IO).";
4312
Barry Warsaw53699e91996-12-10 23:23:01 +00004313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004314posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004315{
4316 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004317 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004318 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004319 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004320 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004321 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004322 if (res < 0)
4323 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004324 Py_INCREF(Py_None);
4325 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004326}
4327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004328
4329static char posix_dup__doc__[] =
4330"dup(fd) -> fd2\n\
4331Return a duplicate of a file descriptor.";
4332
Barry Warsaw53699e91996-12-10 23:23:01 +00004333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004334posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004335{
4336 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004337 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004338 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004339 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004340 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004341 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004342 if (fd < 0)
4343 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004344 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004345}
4346
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004347
4348static char posix_dup2__doc__[] =
4349"dup2(fd, fd2) -> None\n\
4350Duplicate file descriptor.";
4351
Barry Warsaw53699e91996-12-10 23:23:01 +00004352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004353posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004354{
4355 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004356 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004357 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004358 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004359 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004360 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004361 if (res < 0)
4362 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004363 Py_INCREF(Py_None);
4364 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004365}
4366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004367
4368static char posix_lseek__doc__[] =
4369"lseek(fd, pos, how) -> newpos\n\
4370Set the current position of a file descriptor.";
4371
Barry Warsaw53699e91996-12-10 23:23:01 +00004372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004373posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004374{
4375 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00004376#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004377 LONG_LONG pos, res;
4378#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004379 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004380#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004381 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004382 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004383 return NULL;
4384#ifdef SEEK_SET
4385 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4386 switch (how) {
4387 case 0: how = SEEK_SET; break;
4388 case 1: how = SEEK_CUR; break;
4389 case 2: how = SEEK_END; break;
4390 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004391#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004392
4393#if !defined(HAVE_LARGEFILE_SUPPORT)
4394 pos = PyInt_AsLong(posobj);
4395#else
4396 pos = PyLong_Check(posobj) ?
4397 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4398#endif
4399 if (PyErr_Occurred())
4400 return NULL;
4401
Barry Warsaw53699e91996-12-10 23:23:01 +00004402 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00004403#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004404 res = _lseeki64(fd, pos, how);
4405#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004406 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004407#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004408 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004409 if (res < 0)
4410 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004411
4412#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004413 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004414#else
4415 return PyLong_FromLongLong(res);
4416#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004417}
4418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004419
4420static char posix_read__doc__[] =
4421"read(fd, buffersize) -> string\n\
4422Read a file descriptor.";
4423
Barry Warsaw53699e91996-12-10 23:23:01 +00004424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004425posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004426{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004427 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004428 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004429 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004430 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004431 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004432 if (buffer == NULL)
4433 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004434 Py_BEGIN_ALLOW_THREADS
4435 n = read(fd, PyString_AsString(buffer), size);
4436 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004437 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004438 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004439 return posix_error();
4440 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004441 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004442 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004443 return buffer;
4444}
4445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004446
4447static char posix_write__doc__[] =
4448"write(fd, string) -> byteswritten\n\
4449Write a string to a file descriptor.";
4450
Barry Warsaw53699e91996-12-10 23:23:01 +00004451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004452posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004453{
4454 int fd, size;
4455 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004456 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004457 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004458 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004459 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004460 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004461 if (size < 0)
4462 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004463 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004464}
4465
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004466
4467static char posix_fstat__doc__[]=
4468"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
4469Like stat(), but for an open file descriptor.";
4470
Barry Warsaw53699e91996-12-10 23:23:01 +00004471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004472posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004473{
4474 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004475 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004476 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004477 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004478 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004479 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004480 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004481 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004482 if (res != 0)
4483 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004484
Fred Drake699f3522000-06-29 21:12:41 +00004485 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004486}
4487
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004488
4489static char posix_fdopen__doc__[] =
4490"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
4491Return an open file object connected to a file descriptor.";
4492
Barry Warsaw53699e91996-12-10 23:23:01 +00004493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004494posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004495{
Guido van Rossum687dd131993-05-17 08:34:16 +00004496 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004497 char *mode = "r";
4498 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004499 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004500 PyObject *f;
4501 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004502 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004503
Barry Warsaw53699e91996-12-10 23:23:01 +00004504 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004505 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004506 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004507 if (fp == NULL)
4508 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004509 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004510 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004511 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004512 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004513}
4514
Skip Montanaro1517d842000-07-19 14:34:14 +00004515static char posix_isatty__doc__[] =
4516"isatty(fd) -> Boolean\n\
4517Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00004518connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00004519
4520static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004521posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004522{
4523 int fd;
4524 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4525 return NULL;
4526 return Py_BuildValue("i", isatty(fd));
4527}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004528
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004529#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004530static char posix_pipe__doc__[] =
4531"pipe() -> (read_end, write_end)\n\
4532Create a pipe.";
4533
Barry Warsaw53699e91996-12-10 23:23:01 +00004534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004535posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004536{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004537#if defined(PYOS_OS2)
4538 HFILE read, write;
4539 APIRET rc;
4540
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004541 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004542 return NULL;
4543
4544 Py_BEGIN_ALLOW_THREADS
4545 rc = DosCreatePipe( &read, &write, 4096);
4546 Py_END_ALLOW_THREADS
4547 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004548 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004549
4550 return Py_BuildValue("(ii)", read, write);
4551#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00004552#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00004553 int fds[2];
4554 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004555 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004556 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004557 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004558 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004559 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004560 if (res != 0)
4561 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004562 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004563#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00004564 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004565 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004566 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004567 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004568 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004569 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004570 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004571 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004572 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004573 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004574 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4575 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004576 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004577#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004578#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004579}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004580#endif /* HAVE_PIPE */
4581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004582
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004583#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004584static char posix_mkfifo__doc__[] =
4585"mkfifo(file, [, mode=0666]) -> None\n\
4586Create a FIFO (a POSIX named pipe).";
4587
Barry Warsaw53699e91996-12-10 23:23:01 +00004588static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004589posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004590{
4591 char *file;
4592 int mode = 0666;
4593 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004594 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004595 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004596 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004597 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004598 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004599 if (res < 0)
4600 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004601 Py_INCREF(Py_None);
4602 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004603}
4604#endif
4605
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004606
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004607#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004608static char posix_ftruncate__doc__[] =
4609"ftruncate(fd, length) -> None\n\
4610Truncate a file to a specified length.";
4611
Barry Warsaw53699e91996-12-10 23:23:01 +00004612static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004613posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004614{
4615 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004616 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004617 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004618 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004619
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004620 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004621 return NULL;
4622
4623#if !defined(HAVE_LARGEFILE_SUPPORT)
4624 length = PyInt_AsLong(lenobj);
4625#else
4626 length = PyLong_Check(lenobj) ?
4627 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4628#endif
4629 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004630 return NULL;
4631
Barry Warsaw53699e91996-12-10 23:23:01 +00004632 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004633 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004634 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004635 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004636 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004637 return NULL;
4638 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004639 Py_INCREF(Py_None);
4640 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004641}
4642#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004643
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004644#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004645static char posix_putenv__doc__[] =
4646"putenv(key, value) -> None\n\
4647Change or add an environment variable.";
4648
Fred Drake762e2061999-08-26 17:23:54 +00004649/* Save putenv() parameters as values here, so we can collect them when they
4650 * get re-set with another call for the same key. */
4651static PyObject *posix_putenv_garbage;
4652
Tim Peters5aa91602002-01-30 05:46:57 +00004653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004654posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004655{
4656 char *s1, *s2;
4657 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004658 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004659 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004660
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004661 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004662 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004663
4664#if defined(PYOS_OS2)
4665 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4666 APIRET rc;
4667
4668 if (strlen(s2) == 0) /* If New Value is an Empty String */
4669 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4670
4671 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4672 if (rc != NO_ERROR)
4673 return os2_error(rc);
4674
4675 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4676 APIRET rc;
4677
4678 if (strlen(s2) == 0) /* If New Value is an Empty String */
4679 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4680
4681 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4682 if (rc != NO_ERROR)
4683 return os2_error(rc);
4684 } else {
4685#endif
4686
Fred Drake762e2061999-08-26 17:23:54 +00004687 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004688 len = strlen(s1) + strlen(s2) + 2;
4689 /* len includes space for a trailing \0; the size arg to
4690 PyString_FromStringAndSize does not count that */
4691 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004692 if (newstr == NULL)
4693 return PyErr_NoMemory();
4694 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004695 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004696 if (putenv(new)) {
4697 posix_error();
4698 return NULL;
4699 }
Fred Drake762e2061999-08-26 17:23:54 +00004700 /* Install the first arg and newstr in posix_putenv_garbage;
4701 * this will cause previous value to be collected. This has to
4702 * happen after the real putenv() call because the old value
4703 * was still accessible until then. */
4704 if (PyDict_SetItem(posix_putenv_garbage,
4705 PyTuple_GET_ITEM(args, 0), newstr)) {
4706 /* really not much we can do; just leak */
4707 PyErr_Clear();
4708 }
4709 else {
4710 Py_DECREF(newstr);
4711 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004712
4713#if defined(PYOS_OS2)
4714 }
4715#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004716 Py_INCREF(Py_None);
4717 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004718}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004719#endif /* putenv */
4720
Guido van Rossumc524d952001-10-19 01:31:59 +00004721#ifdef HAVE_UNSETENV
4722static char posix_unsetenv__doc__[] =
4723"unsetenv(key) -> None\n\
4724Delete an environment variable.";
4725
4726static PyObject *
4727posix_unsetenv(PyObject *self, PyObject *args)
4728{
4729 char *s1;
4730
4731 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4732 return NULL;
4733
4734 unsetenv(s1);
4735
4736 /* Remove the key from posix_putenv_garbage;
4737 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004738 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004739 * old value was still accessible until then.
4740 */
4741 if (PyDict_DelItem(posix_putenv_garbage,
4742 PyTuple_GET_ITEM(args, 0))) {
4743 /* really not much we can do; just leak */
4744 PyErr_Clear();
4745 }
4746
4747 Py_INCREF(Py_None);
4748 return Py_None;
4749}
4750#endif /* unsetenv */
4751
Guido van Rossumb6a47161997-09-15 22:54:34 +00004752#ifdef HAVE_STRERROR
4753static char posix_strerror__doc__[] =
4754"strerror(code) -> string\n\
4755Translate an error code to a message string.";
4756
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004758posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004759{
4760 int code;
4761 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004762 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004763 return NULL;
4764 message = strerror(code);
4765 if (message == NULL) {
4766 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004767 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004768 return NULL;
4769 }
4770 return PyString_FromString(message);
4771}
4772#endif /* strerror */
4773
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004774
Guido van Rossumc9641791998-08-04 15:26:23 +00004775#ifdef HAVE_SYS_WAIT_H
4776
4777#ifdef WIFSTOPPED
4778static char posix_WIFSTOPPED__doc__[] =
4779"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004780Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004781
4782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004783posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004784{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004785#ifdef UNION_WAIT
4786 union wait status;
4787#define status_i (status.w_status)
4788#else
4789 int status;
4790#define status_i status
4791#endif
4792 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004793
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004794 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004795 {
4796 return NULL;
4797 }
Tim Peters5aa91602002-01-30 05:46:57 +00004798
Guido van Rossumc9641791998-08-04 15:26:23 +00004799 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004800#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004801}
4802#endif /* WIFSTOPPED */
4803
4804#ifdef WIFSIGNALED
4805static char posix_WIFSIGNALED__doc__[] =
4806"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004807Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004808
4809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004810posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004811{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004812#ifdef UNION_WAIT
4813 union wait status;
4814#define status_i (status.w_status)
4815#else
4816 int status;
4817#define status_i status
4818#endif
4819 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004820
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004821 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004822 {
4823 return NULL;
4824 }
Tim Peters5aa91602002-01-30 05:46:57 +00004825
Guido van Rossumc9641791998-08-04 15:26:23 +00004826 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004827#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004828}
4829#endif /* WIFSIGNALED */
4830
4831#ifdef WIFEXITED
4832static char posix_WIFEXITED__doc__[] =
4833"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004834Return true if the process returning 'status' exited using the exit()\n\
4835system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004836
4837static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004838posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004839{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004840#ifdef UNION_WAIT
4841 union wait status;
4842#define status_i (status.w_status)
4843#else
4844 int status;
4845#define status_i status
4846#endif
4847 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004848
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004849 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004850 {
4851 return NULL;
4852 }
Tim Peters5aa91602002-01-30 05:46:57 +00004853
Guido van Rossumc9641791998-08-04 15:26:23 +00004854 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004855#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004856}
4857#endif /* WIFEXITED */
4858
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004859#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004860static char posix_WEXITSTATUS__doc__[] =
4861"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004862Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004863
4864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004865posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004866{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004867#ifdef UNION_WAIT
4868 union wait status;
4869#define status_i (status.w_status)
4870#else
4871 int status;
4872#define status_i status
4873#endif
4874 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004875
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004876 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004877 {
4878 return NULL;
4879 }
Tim Peters5aa91602002-01-30 05:46:57 +00004880
Guido van Rossumc9641791998-08-04 15:26:23 +00004881 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004882#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004883}
4884#endif /* WEXITSTATUS */
4885
4886#ifdef WTERMSIG
4887static char posix_WTERMSIG__doc__[] =
4888"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004889Return the signal that terminated the process that provided the 'status'\n\
4890value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004891
4892static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004893posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004894{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004895#ifdef UNION_WAIT
4896 union wait status;
4897#define status_i (status.w_status)
4898#else
4899 int status;
4900#define status_i status
4901#endif
4902 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004903
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004904 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004905 {
4906 return NULL;
4907 }
Tim Peters5aa91602002-01-30 05:46:57 +00004908
Guido van Rossumc9641791998-08-04 15:26:23 +00004909 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004910#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004911}
4912#endif /* WTERMSIG */
4913
4914#ifdef WSTOPSIG
4915static char posix_WSTOPSIG__doc__[] =
4916"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004917Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004918
4919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004920posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004921{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004922#ifdef UNION_WAIT
4923 union wait status;
4924#define status_i (status.w_status)
4925#else
4926 int status;
4927#define status_i status
4928#endif
4929 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004930
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004931 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004932 {
4933 return NULL;
4934 }
Tim Peters5aa91602002-01-30 05:46:57 +00004935
Guido van Rossumc9641791998-08-04 15:26:23 +00004936 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004937#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004938}
4939#endif /* WSTOPSIG */
4940
4941#endif /* HAVE_SYS_WAIT_H */
4942
4943
Guido van Rossum94f6f721999-01-06 18:42:14 +00004944#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004945#ifdef _SCO_DS
4946/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4947 needed definitions in sys/statvfs.h */
4948#define _SVID3
4949#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004950#include <sys/statvfs.h>
4951
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004952static PyObject*
4953_pystatvfs_fromstructstatvfs(struct statvfs st) {
4954 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4955 if (v == NULL)
4956 return NULL;
4957
4958#if !defined(HAVE_LARGEFILE_SUPPORT)
4959 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4960 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4961 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4962 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4963 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4964 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4965 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4966 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4967 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4968 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4969#else
4970 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4971 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00004972 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004973 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00004974 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004975 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4976 PyStructSequence_SET_ITEM(v, 4,
4977 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00004978 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004979 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00004980 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004981 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00004982 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004983 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4984 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4985 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4986#endif
4987
4988 return v;
4989}
4990
Guido van Rossum94f6f721999-01-06 18:42:14 +00004991static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004992"fstatvfs(fd) -> \n\
4993 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004994Perform an fstatvfs system call on the given fd.";
4995
4996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004997posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004998{
4999 int fd, res;
5000 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005001
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005002 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005003 return NULL;
5004 Py_BEGIN_ALLOW_THREADS
5005 res = fstatvfs(fd, &st);
5006 Py_END_ALLOW_THREADS
5007 if (res != 0)
5008 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005009
5010 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005011}
5012#endif /* HAVE_FSTATVFS */
5013
5014
5015#if defined(HAVE_STATVFS)
5016#include <sys/statvfs.h>
5017
5018static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005019"statvfs(path) -> \n\
5020 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005021Perform a statvfs system call on the given path.";
5022
5023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005024posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005025{
5026 char *path;
5027 int res;
5028 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005029 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005030 return NULL;
5031 Py_BEGIN_ALLOW_THREADS
5032 res = statvfs(path, &st);
5033 Py_END_ALLOW_THREADS
5034 if (res != 0)
5035 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005036
5037 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005038}
5039#endif /* HAVE_STATVFS */
5040
5041
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005042#ifdef HAVE_TEMPNAM
5043static char posix_tempnam__doc__[] = "\
5044tempnam([dir[, prefix]]) -> string\n\
5045Return a unique name for a temporary file.\n\
5046The directory and a short may be specified as strings; they may be omitted\n\
5047or None if not needed.";
5048
5049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005050posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005051{
5052 PyObject *result = NULL;
5053 char *dir = NULL;
5054 char *pfx = NULL;
5055 char *name;
5056
5057 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5058 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005059
5060 if (PyErr_Warn(PyExc_RuntimeWarning,
5061 "tempnam is a potential security risk to your program") < 0)
5062 return NULL;
5063
Fred Drake78b71c22001-07-17 20:37:36 +00005064#ifdef MS_WIN32
5065 name = _tempnam(dir, pfx);
5066#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005067 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005068#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005069 if (name == NULL)
5070 return PyErr_NoMemory();
5071 result = PyString_FromString(name);
5072 free(name);
5073 return result;
5074}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005075#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005076
5077
5078#ifdef HAVE_TMPFILE
5079static char posix_tmpfile__doc__[] = "\
5080tmpfile() -> file object\n\
5081Create a temporary file with no directory entries.";
5082
5083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005084posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005085{
5086 FILE *fp;
5087
5088 if (!PyArg_ParseTuple(args, ":tmpfile"))
5089 return NULL;
5090 fp = tmpfile();
5091 if (fp == NULL)
5092 return posix_error();
5093 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
5094}
5095#endif
5096
5097
5098#ifdef HAVE_TMPNAM
5099static char posix_tmpnam__doc__[] = "\
5100tmpnam() -> string\n\
5101Return a unique name for a temporary file.";
5102
5103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005104posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005105{
5106 char buffer[L_tmpnam];
5107 char *name;
5108
5109 if (!PyArg_ParseTuple(args, ":tmpnam"))
5110 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005111
5112 if (PyErr_Warn(PyExc_RuntimeWarning,
5113 "tmpnam is a potential security risk to your program") < 0)
5114 return NULL;
5115
Greg Wardb48bc172000-03-01 21:51:56 +00005116#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005117 name = tmpnam_r(buffer);
5118#else
5119 name = tmpnam(buffer);
5120#endif
5121 if (name == NULL) {
5122 PyErr_SetObject(PyExc_OSError,
5123 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005124#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005125 "unexpected NULL from tmpnam_r"
5126#else
5127 "unexpected NULL from tmpnam"
5128#endif
5129 ));
5130 return NULL;
5131 }
5132 return PyString_FromString(buffer);
5133}
5134#endif
5135
5136
Fred Drakec9680921999-12-13 16:37:25 +00005137/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5138 * It maps strings representing configuration variable names to
5139 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005140 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005141 * rarely-used constants. There are three separate tables that use
5142 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005143 *
5144 * This code is always included, even if none of the interfaces that
5145 * need it are included. The #if hackery needed to avoid it would be
5146 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005147 */
5148struct constdef {
5149 char *name;
5150 long value;
5151};
5152
Fred Drake12c6e2d1999-12-14 21:25:03 +00005153static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005154conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5155 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005156{
5157 if (PyInt_Check(arg)) {
5158 *valuep = PyInt_AS_LONG(arg);
5159 return 1;
5160 }
5161 if (PyString_Check(arg)) {
5162 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005163 size_t lo = 0;
5164 size_t mid;
5165 size_t hi = tablesize;
5166 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005167 char *confname = PyString_AS_STRING(arg);
5168 while (lo < hi) {
5169 mid = (lo + hi) / 2;
5170 cmp = strcmp(confname, table[mid].name);
5171 if (cmp < 0)
5172 hi = mid;
5173 else if (cmp > 0)
5174 lo = mid + 1;
5175 else {
5176 *valuep = table[mid].value;
5177 return 1;
5178 }
5179 }
5180 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5181 }
5182 else
5183 PyErr_SetString(PyExc_TypeError,
5184 "configuration names must be strings or integers");
5185 return 0;
5186}
5187
5188
5189#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5190static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005191#ifdef _PC_ABI_AIO_XFER_MAX
5192 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5193#endif
5194#ifdef _PC_ABI_ASYNC_IO
5195 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5196#endif
Fred Drakec9680921999-12-13 16:37:25 +00005197#ifdef _PC_ASYNC_IO
5198 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5199#endif
5200#ifdef _PC_CHOWN_RESTRICTED
5201 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5202#endif
5203#ifdef _PC_FILESIZEBITS
5204 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5205#endif
5206#ifdef _PC_LAST
5207 {"PC_LAST", _PC_LAST},
5208#endif
5209#ifdef _PC_LINK_MAX
5210 {"PC_LINK_MAX", _PC_LINK_MAX},
5211#endif
5212#ifdef _PC_MAX_CANON
5213 {"PC_MAX_CANON", _PC_MAX_CANON},
5214#endif
5215#ifdef _PC_MAX_INPUT
5216 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5217#endif
5218#ifdef _PC_NAME_MAX
5219 {"PC_NAME_MAX", _PC_NAME_MAX},
5220#endif
5221#ifdef _PC_NO_TRUNC
5222 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5223#endif
5224#ifdef _PC_PATH_MAX
5225 {"PC_PATH_MAX", _PC_PATH_MAX},
5226#endif
5227#ifdef _PC_PIPE_BUF
5228 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5229#endif
5230#ifdef _PC_PRIO_IO
5231 {"PC_PRIO_IO", _PC_PRIO_IO},
5232#endif
5233#ifdef _PC_SOCK_MAXBUF
5234 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5235#endif
5236#ifdef _PC_SYNC_IO
5237 {"PC_SYNC_IO", _PC_SYNC_IO},
5238#endif
5239#ifdef _PC_VDISABLE
5240 {"PC_VDISABLE", _PC_VDISABLE},
5241#endif
5242};
5243
Fred Drakec9680921999-12-13 16:37:25 +00005244static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005245conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005246{
5247 return conv_confname(arg, valuep, posix_constants_pathconf,
5248 sizeof(posix_constants_pathconf)
5249 / sizeof(struct constdef));
5250}
5251#endif
5252
5253#ifdef HAVE_FPATHCONF
5254static char posix_fpathconf__doc__[] = "\
5255fpathconf(fd, name) -> integer\n\
5256Return the configuration limit name for the file descriptor fd.\n\
5257If there is no limit, return -1.";
5258
5259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005260posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005261{
5262 PyObject *result = NULL;
5263 int name, fd;
5264
Fred Drake12c6e2d1999-12-14 21:25:03 +00005265 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5266 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005267 long limit;
5268
5269 errno = 0;
5270 limit = fpathconf(fd, name);
5271 if (limit == -1 && errno != 0)
5272 posix_error();
5273 else
5274 result = PyInt_FromLong(limit);
5275 }
5276 return result;
5277}
5278#endif
5279
5280
5281#ifdef HAVE_PATHCONF
5282static char posix_pathconf__doc__[] = "\
5283pathconf(path, name) -> integer\n\
5284Return the configuration limit name for the file or directory path.\n\
5285If there is no limit, return -1.";
5286
5287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005288posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005289{
5290 PyObject *result = NULL;
5291 int name;
5292 char *path;
5293
5294 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5295 conv_path_confname, &name)) {
5296 long limit;
5297
5298 errno = 0;
5299 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005300 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005301 if (errno == EINVAL)
5302 /* could be a path or name problem */
5303 posix_error();
5304 else
5305 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005306 }
Fred Drakec9680921999-12-13 16:37:25 +00005307 else
5308 result = PyInt_FromLong(limit);
5309 }
5310 return result;
5311}
5312#endif
5313
5314#ifdef HAVE_CONFSTR
5315static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005316#ifdef _CS_ARCHITECTURE
5317 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5318#endif
5319#ifdef _CS_HOSTNAME
5320 {"CS_HOSTNAME", _CS_HOSTNAME},
5321#endif
5322#ifdef _CS_HW_PROVIDER
5323 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5324#endif
5325#ifdef _CS_HW_SERIAL
5326 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5327#endif
5328#ifdef _CS_INITTAB_NAME
5329 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5330#endif
Fred Drakec9680921999-12-13 16:37:25 +00005331#ifdef _CS_LFS64_CFLAGS
5332 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5333#endif
5334#ifdef _CS_LFS64_LDFLAGS
5335 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5336#endif
5337#ifdef _CS_LFS64_LIBS
5338 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5339#endif
5340#ifdef _CS_LFS64_LINTFLAGS
5341 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5342#endif
5343#ifdef _CS_LFS_CFLAGS
5344 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5345#endif
5346#ifdef _CS_LFS_LDFLAGS
5347 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5348#endif
5349#ifdef _CS_LFS_LIBS
5350 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5351#endif
5352#ifdef _CS_LFS_LINTFLAGS
5353 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5354#endif
Fred Draked86ed291999-12-15 15:34:33 +00005355#ifdef _CS_MACHINE
5356 {"CS_MACHINE", _CS_MACHINE},
5357#endif
Fred Drakec9680921999-12-13 16:37:25 +00005358#ifdef _CS_PATH
5359 {"CS_PATH", _CS_PATH},
5360#endif
Fred Draked86ed291999-12-15 15:34:33 +00005361#ifdef _CS_RELEASE
5362 {"CS_RELEASE", _CS_RELEASE},
5363#endif
5364#ifdef _CS_SRPC_DOMAIN
5365 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5366#endif
5367#ifdef _CS_SYSNAME
5368 {"CS_SYSNAME", _CS_SYSNAME},
5369#endif
5370#ifdef _CS_VERSION
5371 {"CS_VERSION", _CS_VERSION},
5372#endif
Fred Drakec9680921999-12-13 16:37:25 +00005373#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5374 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5375#endif
5376#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5377 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5378#endif
5379#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5380 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5381#endif
5382#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5383 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5384#endif
5385#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5386 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5387#endif
5388#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5389 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5390#endif
5391#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5392 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5393#endif
5394#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5395 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5396#endif
5397#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5398 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5399#endif
5400#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5401 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5402#endif
5403#ifdef _CS_XBS5_LP64_OFF64_LIBS
5404 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5405#endif
5406#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5407 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5408#endif
5409#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5410 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5411#endif
5412#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5413 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5414#endif
5415#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5416 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5417#endif
5418#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5419 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5420#endif
Fred Draked86ed291999-12-15 15:34:33 +00005421#ifdef _MIPS_CS_AVAIL_PROCESSORS
5422 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5423#endif
5424#ifdef _MIPS_CS_BASE
5425 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5426#endif
5427#ifdef _MIPS_CS_HOSTID
5428 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5429#endif
5430#ifdef _MIPS_CS_HW_NAME
5431 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5432#endif
5433#ifdef _MIPS_CS_NUM_PROCESSORS
5434 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5435#endif
5436#ifdef _MIPS_CS_OSREL_MAJ
5437 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5438#endif
5439#ifdef _MIPS_CS_OSREL_MIN
5440 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5441#endif
5442#ifdef _MIPS_CS_OSREL_PATCH
5443 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5444#endif
5445#ifdef _MIPS_CS_OS_NAME
5446 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5447#endif
5448#ifdef _MIPS_CS_OS_PROVIDER
5449 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5450#endif
5451#ifdef _MIPS_CS_PROCESSORS
5452 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5453#endif
5454#ifdef _MIPS_CS_SERIAL
5455 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5456#endif
5457#ifdef _MIPS_CS_VENDOR
5458 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5459#endif
Fred Drakec9680921999-12-13 16:37:25 +00005460};
5461
5462static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005463conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005464{
5465 return conv_confname(arg, valuep, posix_constants_confstr,
5466 sizeof(posix_constants_confstr)
5467 / sizeof(struct constdef));
5468}
5469
5470static char posix_confstr__doc__[] = "\
5471confstr(name) -> string\n\
5472Return a string-valued system configuration variable.";
5473
5474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005475posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005476{
5477 PyObject *result = NULL;
5478 int name;
5479 char buffer[64];
5480
5481 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5482 int len = confstr(name, buffer, sizeof(buffer));
5483
Fred Drakec9680921999-12-13 16:37:25 +00005484 errno = 0;
5485 if (len == 0) {
5486 if (errno != 0)
5487 posix_error();
5488 else
5489 result = PyString_FromString("");
5490 }
5491 else {
5492 if (len >= sizeof(buffer)) {
5493 result = PyString_FromStringAndSize(NULL, len);
5494 if (result != NULL)
5495 confstr(name, PyString_AS_STRING(result), len+1);
5496 }
5497 else
5498 result = PyString_FromString(buffer);
5499 }
5500 }
5501 return result;
5502}
5503#endif
5504
5505
5506#ifdef HAVE_SYSCONF
5507static struct constdef posix_constants_sysconf[] = {
5508#ifdef _SC_2_CHAR_TERM
5509 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5510#endif
5511#ifdef _SC_2_C_BIND
5512 {"SC_2_C_BIND", _SC_2_C_BIND},
5513#endif
5514#ifdef _SC_2_C_DEV
5515 {"SC_2_C_DEV", _SC_2_C_DEV},
5516#endif
5517#ifdef _SC_2_C_VERSION
5518 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5519#endif
5520#ifdef _SC_2_FORT_DEV
5521 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5522#endif
5523#ifdef _SC_2_FORT_RUN
5524 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5525#endif
5526#ifdef _SC_2_LOCALEDEF
5527 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5528#endif
5529#ifdef _SC_2_SW_DEV
5530 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5531#endif
5532#ifdef _SC_2_UPE
5533 {"SC_2_UPE", _SC_2_UPE},
5534#endif
5535#ifdef _SC_2_VERSION
5536 {"SC_2_VERSION", _SC_2_VERSION},
5537#endif
Fred Draked86ed291999-12-15 15:34:33 +00005538#ifdef _SC_ABI_ASYNCHRONOUS_IO
5539 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5540#endif
5541#ifdef _SC_ACL
5542 {"SC_ACL", _SC_ACL},
5543#endif
Fred Drakec9680921999-12-13 16:37:25 +00005544#ifdef _SC_AIO_LISTIO_MAX
5545 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5546#endif
Fred Drakec9680921999-12-13 16:37:25 +00005547#ifdef _SC_AIO_MAX
5548 {"SC_AIO_MAX", _SC_AIO_MAX},
5549#endif
5550#ifdef _SC_AIO_PRIO_DELTA_MAX
5551 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5552#endif
5553#ifdef _SC_ARG_MAX
5554 {"SC_ARG_MAX", _SC_ARG_MAX},
5555#endif
5556#ifdef _SC_ASYNCHRONOUS_IO
5557 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5558#endif
5559#ifdef _SC_ATEXIT_MAX
5560 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5561#endif
Fred Draked86ed291999-12-15 15:34:33 +00005562#ifdef _SC_AUDIT
5563 {"SC_AUDIT", _SC_AUDIT},
5564#endif
Fred Drakec9680921999-12-13 16:37:25 +00005565#ifdef _SC_AVPHYS_PAGES
5566 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5567#endif
5568#ifdef _SC_BC_BASE_MAX
5569 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5570#endif
5571#ifdef _SC_BC_DIM_MAX
5572 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5573#endif
5574#ifdef _SC_BC_SCALE_MAX
5575 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5576#endif
5577#ifdef _SC_BC_STRING_MAX
5578 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5579#endif
Fred Draked86ed291999-12-15 15:34:33 +00005580#ifdef _SC_CAP
5581 {"SC_CAP", _SC_CAP},
5582#endif
Fred Drakec9680921999-12-13 16:37:25 +00005583#ifdef _SC_CHARCLASS_NAME_MAX
5584 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5585#endif
5586#ifdef _SC_CHAR_BIT
5587 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5588#endif
5589#ifdef _SC_CHAR_MAX
5590 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5591#endif
5592#ifdef _SC_CHAR_MIN
5593 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5594#endif
5595#ifdef _SC_CHILD_MAX
5596 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5597#endif
5598#ifdef _SC_CLK_TCK
5599 {"SC_CLK_TCK", _SC_CLK_TCK},
5600#endif
5601#ifdef _SC_COHER_BLKSZ
5602 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5603#endif
5604#ifdef _SC_COLL_WEIGHTS_MAX
5605 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5606#endif
5607#ifdef _SC_DCACHE_ASSOC
5608 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5609#endif
5610#ifdef _SC_DCACHE_BLKSZ
5611 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5612#endif
5613#ifdef _SC_DCACHE_LINESZ
5614 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5615#endif
5616#ifdef _SC_DCACHE_SZ
5617 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5618#endif
5619#ifdef _SC_DCACHE_TBLKSZ
5620 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5621#endif
5622#ifdef _SC_DELAYTIMER_MAX
5623 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5624#endif
5625#ifdef _SC_EQUIV_CLASS_MAX
5626 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5627#endif
5628#ifdef _SC_EXPR_NEST_MAX
5629 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5630#endif
5631#ifdef _SC_FSYNC
5632 {"SC_FSYNC", _SC_FSYNC},
5633#endif
5634#ifdef _SC_GETGR_R_SIZE_MAX
5635 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5636#endif
5637#ifdef _SC_GETPW_R_SIZE_MAX
5638 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5639#endif
5640#ifdef _SC_ICACHE_ASSOC
5641 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5642#endif
5643#ifdef _SC_ICACHE_BLKSZ
5644 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5645#endif
5646#ifdef _SC_ICACHE_LINESZ
5647 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5648#endif
5649#ifdef _SC_ICACHE_SZ
5650 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5651#endif
Fred Draked86ed291999-12-15 15:34:33 +00005652#ifdef _SC_INF
5653 {"SC_INF", _SC_INF},
5654#endif
Fred Drakec9680921999-12-13 16:37:25 +00005655#ifdef _SC_INT_MAX
5656 {"SC_INT_MAX", _SC_INT_MAX},
5657#endif
5658#ifdef _SC_INT_MIN
5659 {"SC_INT_MIN", _SC_INT_MIN},
5660#endif
5661#ifdef _SC_IOV_MAX
5662 {"SC_IOV_MAX", _SC_IOV_MAX},
5663#endif
Fred Draked86ed291999-12-15 15:34:33 +00005664#ifdef _SC_IP_SECOPTS
5665 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5666#endif
Fred Drakec9680921999-12-13 16:37:25 +00005667#ifdef _SC_JOB_CONTROL
5668 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5669#endif
Fred Draked86ed291999-12-15 15:34:33 +00005670#ifdef _SC_KERN_POINTERS
5671 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5672#endif
5673#ifdef _SC_KERN_SIM
5674 {"SC_KERN_SIM", _SC_KERN_SIM},
5675#endif
Fred Drakec9680921999-12-13 16:37:25 +00005676#ifdef _SC_LINE_MAX
5677 {"SC_LINE_MAX", _SC_LINE_MAX},
5678#endif
5679#ifdef _SC_LOGIN_NAME_MAX
5680 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5681#endif
5682#ifdef _SC_LOGNAME_MAX
5683 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5684#endif
5685#ifdef _SC_LONG_BIT
5686 {"SC_LONG_BIT", _SC_LONG_BIT},
5687#endif
Fred Draked86ed291999-12-15 15:34:33 +00005688#ifdef _SC_MAC
5689 {"SC_MAC", _SC_MAC},
5690#endif
Fred Drakec9680921999-12-13 16:37:25 +00005691#ifdef _SC_MAPPED_FILES
5692 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5693#endif
5694#ifdef _SC_MAXPID
5695 {"SC_MAXPID", _SC_MAXPID},
5696#endif
5697#ifdef _SC_MB_LEN_MAX
5698 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5699#endif
5700#ifdef _SC_MEMLOCK
5701 {"SC_MEMLOCK", _SC_MEMLOCK},
5702#endif
5703#ifdef _SC_MEMLOCK_RANGE
5704 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5705#endif
5706#ifdef _SC_MEMORY_PROTECTION
5707 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5708#endif
5709#ifdef _SC_MESSAGE_PASSING
5710 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5711#endif
Fred Draked86ed291999-12-15 15:34:33 +00005712#ifdef _SC_MMAP_FIXED_ALIGNMENT
5713 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5714#endif
Fred Drakec9680921999-12-13 16:37:25 +00005715#ifdef _SC_MQ_OPEN_MAX
5716 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5717#endif
5718#ifdef _SC_MQ_PRIO_MAX
5719 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5720#endif
Fred Draked86ed291999-12-15 15:34:33 +00005721#ifdef _SC_NACLS_MAX
5722 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5723#endif
Fred Drakec9680921999-12-13 16:37:25 +00005724#ifdef _SC_NGROUPS_MAX
5725 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5726#endif
5727#ifdef _SC_NL_ARGMAX
5728 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5729#endif
5730#ifdef _SC_NL_LANGMAX
5731 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5732#endif
5733#ifdef _SC_NL_MSGMAX
5734 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5735#endif
5736#ifdef _SC_NL_NMAX
5737 {"SC_NL_NMAX", _SC_NL_NMAX},
5738#endif
5739#ifdef _SC_NL_SETMAX
5740 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5741#endif
5742#ifdef _SC_NL_TEXTMAX
5743 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5744#endif
5745#ifdef _SC_NPROCESSORS_CONF
5746 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5747#endif
5748#ifdef _SC_NPROCESSORS_ONLN
5749 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5750#endif
Fred Draked86ed291999-12-15 15:34:33 +00005751#ifdef _SC_NPROC_CONF
5752 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5753#endif
5754#ifdef _SC_NPROC_ONLN
5755 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5756#endif
Fred Drakec9680921999-12-13 16:37:25 +00005757#ifdef _SC_NZERO
5758 {"SC_NZERO", _SC_NZERO},
5759#endif
5760#ifdef _SC_OPEN_MAX
5761 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5762#endif
5763#ifdef _SC_PAGESIZE
5764 {"SC_PAGESIZE", _SC_PAGESIZE},
5765#endif
5766#ifdef _SC_PAGE_SIZE
5767 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5768#endif
5769#ifdef _SC_PASS_MAX
5770 {"SC_PASS_MAX", _SC_PASS_MAX},
5771#endif
5772#ifdef _SC_PHYS_PAGES
5773 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5774#endif
5775#ifdef _SC_PII
5776 {"SC_PII", _SC_PII},
5777#endif
5778#ifdef _SC_PII_INTERNET
5779 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5780#endif
5781#ifdef _SC_PII_INTERNET_DGRAM
5782 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5783#endif
5784#ifdef _SC_PII_INTERNET_STREAM
5785 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5786#endif
5787#ifdef _SC_PII_OSI
5788 {"SC_PII_OSI", _SC_PII_OSI},
5789#endif
5790#ifdef _SC_PII_OSI_CLTS
5791 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5792#endif
5793#ifdef _SC_PII_OSI_COTS
5794 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5795#endif
5796#ifdef _SC_PII_OSI_M
5797 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5798#endif
5799#ifdef _SC_PII_SOCKET
5800 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5801#endif
5802#ifdef _SC_PII_XTI
5803 {"SC_PII_XTI", _SC_PII_XTI},
5804#endif
5805#ifdef _SC_POLL
5806 {"SC_POLL", _SC_POLL},
5807#endif
5808#ifdef _SC_PRIORITIZED_IO
5809 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5810#endif
5811#ifdef _SC_PRIORITY_SCHEDULING
5812 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5813#endif
5814#ifdef _SC_REALTIME_SIGNALS
5815 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5816#endif
5817#ifdef _SC_RE_DUP_MAX
5818 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5819#endif
5820#ifdef _SC_RTSIG_MAX
5821 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5822#endif
5823#ifdef _SC_SAVED_IDS
5824 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5825#endif
5826#ifdef _SC_SCHAR_MAX
5827 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5828#endif
5829#ifdef _SC_SCHAR_MIN
5830 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5831#endif
5832#ifdef _SC_SELECT
5833 {"SC_SELECT", _SC_SELECT},
5834#endif
5835#ifdef _SC_SEMAPHORES
5836 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5837#endif
5838#ifdef _SC_SEM_NSEMS_MAX
5839 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5840#endif
5841#ifdef _SC_SEM_VALUE_MAX
5842 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5843#endif
5844#ifdef _SC_SHARED_MEMORY_OBJECTS
5845 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5846#endif
5847#ifdef _SC_SHRT_MAX
5848 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5849#endif
5850#ifdef _SC_SHRT_MIN
5851 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5852#endif
5853#ifdef _SC_SIGQUEUE_MAX
5854 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5855#endif
5856#ifdef _SC_SIGRT_MAX
5857 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5858#endif
5859#ifdef _SC_SIGRT_MIN
5860 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5861#endif
Fred Draked86ed291999-12-15 15:34:33 +00005862#ifdef _SC_SOFTPOWER
5863 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5864#endif
Fred Drakec9680921999-12-13 16:37:25 +00005865#ifdef _SC_SPLIT_CACHE
5866 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5867#endif
5868#ifdef _SC_SSIZE_MAX
5869 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5870#endif
5871#ifdef _SC_STACK_PROT
5872 {"SC_STACK_PROT", _SC_STACK_PROT},
5873#endif
5874#ifdef _SC_STREAM_MAX
5875 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5876#endif
5877#ifdef _SC_SYNCHRONIZED_IO
5878 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5879#endif
5880#ifdef _SC_THREADS
5881 {"SC_THREADS", _SC_THREADS},
5882#endif
5883#ifdef _SC_THREAD_ATTR_STACKADDR
5884 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5885#endif
5886#ifdef _SC_THREAD_ATTR_STACKSIZE
5887 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5888#endif
5889#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5890 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5891#endif
5892#ifdef _SC_THREAD_KEYS_MAX
5893 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5894#endif
5895#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5896 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5897#endif
5898#ifdef _SC_THREAD_PRIO_INHERIT
5899 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5900#endif
5901#ifdef _SC_THREAD_PRIO_PROTECT
5902 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5903#endif
5904#ifdef _SC_THREAD_PROCESS_SHARED
5905 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5906#endif
5907#ifdef _SC_THREAD_SAFE_FUNCTIONS
5908 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5909#endif
5910#ifdef _SC_THREAD_STACK_MIN
5911 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5912#endif
5913#ifdef _SC_THREAD_THREADS_MAX
5914 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5915#endif
5916#ifdef _SC_TIMERS
5917 {"SC_TIMERS", _SC_TIMERS},
5918#endif
5919#ifdef _SC_TIMER_MAX
5920 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5921#endif
5922#ifdef _SC_TTY_NAME_MAX
5923 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5924#endif
5925#ifdef _SC_TZNAME_MAX
5926 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5927#endif
5928#ifdef _SC_T_IOV_MAX
5929 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5930#endif
5931#ifdef _SC_UCHAR_MAX
5932 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5933#endif
5934#ifdef _SC_UINT_MAX
5935 {"SC_UINT_MAX", _SC_UINT_MAX},
5936#endif
5937#ifdef _SC_UIO_MAXIOV
5938 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5939#endif
5940#ifdef _SC_ULONG_MAX
5941 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5942#endif
5943#ifdef _SC_USHRT_MAX
5944 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5945#endif
5946#ifdef _SC_VERSION
5947 {"SC_VERSION", _SC_VERSION},
5948#endif
5949#ifdef _SC_WORD_BIT
5950 {"SC_WORD_BIT", _SC_WORD_BIT},
5951#endif
5952#ifdef _SC_XBS5_ILP32_OFF32
5953 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5954#endif
5955#ifdef _SC_XBS5_ILP32_OFFBIG
5956 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5957#endif
5958#ifdef _SC_XBS5_LP64_OFF64
5959 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5960#endif
5961#ifdef _SC_XBS5_LPBIG_OFFBIG
5962 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5963#endif
5964#ifdef _SC_XOPEN_CRYPT
5965 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5966#endif
5967#ifdef _SC_XOPEN_ENH_I18N
5968 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5969#endif
5970#ifdef _SC_XOPEN_LEGACY
5971 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5972#endif
5973#ifdef _SC_XOPEN_REALTIME
5974 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5975#endif
5976#ifdef _SC_XOPEN_REALTIME_THREADS
5977 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5978#endif
5979#ifdef _SC_XOPEN_SHM
5980 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5981#endif
5982#ifdef _SC_XOPEN_UNIX
5983 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5984#endif
5985#ifdef _SC_XOPEN_VERSION
5986 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5987#endif
5988#ifdef _SC_XOPEN_XCU_VERSION
5989 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5990#endif
5991#ifdef _SC_XOPEN_XPG2
5992 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5993#endif
5994#ifdef _SC_XOPEN_XPG3
5995 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5996#endif
5997#ifdef _SC_XOPEN_XPG4
5998 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5999#endif
6000};
6001
6002static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006003conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006004{
6005 return conv_confname(arg, valuep, posix_constants_sysconf,
6006 sizeof(posix_constants_sysconf)
6007 / sizeof(struct constdef));
6008}
6009
6010static char posix_sysconf__doc__[] = "\
6011sysconf(name) -> integer\n\
6012Return an integer-valued system configuration variable.";
6013
6014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006015posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006016{
6017 PyObject *result = NULL;
6018 int name;
6019
6020 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6021 int value;
6022
6023 errno = 0;
6024 value = sysconf(name);
6025 if (value == -1 && errno != 0)
6026 posix_error();
6027 else
6028 result = PyInt_FromLong(value);
6029 }
6030 return result;
6031}
6032#endif
6033
6034
Fred Drakebec628d1999-12-15 18:31:10 +00006035/* This code is used to ensure that the tables of configuration value names
6036 * are in sorted order as required by conv_confname(), and also to build the
6037 * the exported dictionaries that are used to publish information about the
6038 * names available on the host platform.
6039 *
6040 * Sorting the table at runtime ensures that the table is properly ordered
6041 * when used, even for platforms we're not able to test on. It also makes
6042 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006043 */
Fred Drakebec628d1999-12-15 18:31:10 +00006044
6045static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006046cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006047{
6048 const struct constdef *c1 =
6049 (const struct constdef *) v1;
6050 const struct constdef *c2 =
6051 (const struct constdef *) v2;
6052
6053 return strcmp(c1->name, c2->name);
6054}
6055
6056static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006057setup_confname_table(struct constdef *table, size_t tablesize,
6058 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00006059{
Fred Drakebec628d1999-12-15 18:31:10 +00006060 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006061 size_t i;
6062 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00006063
6064 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6065 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006066 if (d == NULL)
6067 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006068
Barry Warsaw3155db32000-04-13 15:20:40 +00006069 for (i=0; i < tablesize; ++i) {
6070 PyObject *o = PyInt_FromLong(table[i].value);
6071 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6072 Py_XDECREF(o);
6073 Py_DECREF(d);
6074 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006075 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006076 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006077 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006078 status = PyDict_SetItemString(moddict, tablename, d);
6079 Py_DECREF(d);
6080 return status;
Fred Draked86ed291999-12-15 15:34:33 +00006081}
6082
Fred Drakebec628d1999-12-15 18:31:10 +00006083/* Return -1 on failure, 0 on success. */
6084static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006085setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00006086{
6087#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006088 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006089 sizeof(posix_constants_pathconf)
6090 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006091 "pathconf_names", moddict))
6092 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006093#endif
6094#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006095 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006096 sizeof(posix_constants_confstr)
6097 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006098 "confstr_names", moddict))
6099 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006100#endif
6101#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006102 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006103 sizeof(posix_constants_sysconf)
6104 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006105 "sysconf_names", moddict))
6106 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006107#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006108 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006109}
Fred Draked86ed291999-12-15 15:34:33 +00006110
6111
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006112static char posix_abort__doc__[] = "\
6113abort() -> does not return!\n\
6114Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
6115in the hardest way possible on the hosting operating system.";
6116
6117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006118posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006119{
6120 if (!PyArg_ParseTuple(args, ":abort"))
6121 return NULL;
6122 abort();
6123 /*NOTREACHED*/
6124 Py_FatalError("abort() called from Python code didn't abort!");
6125 return NULL;
6126}
Fred Drakebec628d1999-12-15 18:31:10 +00006127
Tim Petersf58a7aa2000-09-22 10:05:54 +00006128#ifdef MS_WIN32
6129static char win32_startfile__doc__[] = "\
6130startfile(filepath) - Start a file with its associated application.\n\
6131\n\
6132This acts like double-clicking the file in Explorer, or giving the file\n\
6133name as an argument to the DOS \"start\" command: the file is opened\n\
6134with whatever application (if any) its extension is associated.\n\
6135\n\
6136startfile returns as soon as the associated application is launched.\n\
6137There is no option to wait for the application to close, and no way\n\
6138to retrieve the application's exit status.\n\
6139\n\
6140The filepath is relative to the current directory. If you want to use\n\
6141an absolute path, make sure the first character is not a slash (\"/\");\n\
6142the underlying Win32 ShellExecute function doesn't work if it is.";
6143
6144static PyObject *
6145win32_startfile(PyObject *self, PyObject *args)
6146{
6147 char *filepath;
6148 HINSTANCE rc;
6149 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6150 return NULL;
6151 Py_BEGIN_ALLOW_THREADS
6152 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6153 Py_END_ALLOW_THREADS
6154 if (rc <= (HINSTANCE)32)
6155 return win32_error("startfile", filepath);
6156 Py_INCREF(Py_None);
6157 return Py_None;
6158}
6159#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006160
6161static PyMethodDef posix_methods[] = {
6162 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6163#ifdef HAVE_TTYNAME
6164 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6165#endif
6166 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6167 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006168#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006169 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006170#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006171#ifdef HAVE_CHROOT
6172 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6173#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006174#ifdef HAVE_CTERMID
6175 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6176#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006177#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006178 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006179#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006180#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006181 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006182#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006183 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6184 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6185 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006186#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006187 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006188#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006189#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006190 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006191#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006192 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6193 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6194 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006195#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006196 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006197#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006198#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006199 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006200#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006201 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006202#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006203 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006204#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006205 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6206 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6207 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006208#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006209 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006210#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006211 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006212#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006213 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6214 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006215#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006216#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006217 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6218 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006219#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006220#ifdef HAVE_FORK1
6221 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6222#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006223#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006224 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006225#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006226#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006227 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006228#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006229#ifdef HAVE_FORKPTY
6230 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6231#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006232#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006233 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006234#endif /* HAVE_GETEGID */
6235#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006236 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006237#endif /* HAVE_GETEUID */
6238#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006239 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006240#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006241#ifdef HAVE_GETGROUPS
6242 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6243#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006244 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006245#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006246 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006247#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006248#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006249 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006250#endif /* HAVE_GETPPID */
6251#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006252 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006253#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006254#ifdef HAVE_GETLOGIN
6255 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6256#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006257#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006258 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006259#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006260#ifdef HAVE_KILLPG
6261 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6262#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006263#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006264 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006265#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006266#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006267 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006268#ifdef MS_WIN32
6269 {"popen2", win32_popen2, METH_VARARGS},
6270 {"popen3", win32_popen3, METH_VARARGS},
6271 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006272 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006273#else
6274#if defined(PYOS_OS2) && defined(PYCC_GCC)
6275 {"popen2", os2emx_popen2, METH_VARARGS},
6276 {"popen3", os2emx_popen3, METH_VARARGS},
6277 {"popen4", os2emx_popen4, METH_VARARGS},
6278#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006279#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006280#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006281#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006282 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006283#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006284#ifdef HAVE_SETEUID
6285 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6286#endif /* HAVE_SETEUID */
6287#ifdef HAVE_SETEGID
6288 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6289#endif /* HAVE_SETEGID */
6290#ifdef HAVE_SETREUID
6291 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6292#endif /* HAVE_SETREUID */
6293#ifdef HAVE_SETREGID
6294 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6295#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006296#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006297 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006298#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006299#ifdef HAVE_SETGROUPS
6300 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6301#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006302#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006303 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006304#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006305#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006306 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006307#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006308#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006309 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006310#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006311#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006312 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006313#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006314#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006315 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006316#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006317#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006318 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006319#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006320#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006321 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006322#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006323 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6324 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6325 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6326 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6327 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6328 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6329 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6330 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6331 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006332 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006333#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006334 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006335#endif
6336#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006337 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006338#endif
6339#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006340 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006341#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006342#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006343 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006344#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006345#ifdef HAVE_UNSETENV
6346 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6347#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006348#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006349 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006350#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006351#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006352 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006353#endif
6354#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006355 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006356#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006357#ifdef HAVE_SYS_WAIT_H
6358#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006359 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006360#endif /* WIFSTOPPED */
6361#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006362 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006363#endif /* WIFSIGNALED */
6364#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006366#endif /* WIFEXITED */
6367#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006368 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006369#endif /* WEXITSTATUS */
6370#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006371 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006372#endif /* WTERMSIG */
6373#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006374 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006375#endif /* WSTOPSIG */
6376#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006377#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006378 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006379#endif
6380#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006381 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006382#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006383#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006384 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6385#endif
6386#ifdef HAVE_TEMPNAM
6387 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6388#endif
6389#ifdef HAVE_TMPNAM
6390 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6391#endif
Fred Drakec9680921999-12-13 16:37:25 +00006392#ifdef HAVE_CONFSTR
6393 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6394#endif
6395#ifdef HAVE_SYSCONF
6396 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6397#endif
6398#ifdef HAVE_FPATHCONF
6399 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6400#endif
6401#ifdef HAVE_PATHCONF
6402 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6403#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006404 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00006405#ifdef MS_WIN32
6406 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6407#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006408 {NULL, NULL} /* Sentinel */
6409};
6410
6411
Barry Warsaw4a342091996-12-19 23:50:02 +00006412static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006413ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006414{
6415 PyObject* v = PyInt_FromLong(value);
6416 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
6417 return -1; /* triggers fatal error */
6418
6419 Py_DECREF(v);
6420 return 0;
6421}
6422
Guido van Rossumd48f2521997-12-05 22:19:34 +00006423#if defined(PYOS_OS2)
6424/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
6425static int insertvalues(PyObject *d)
6426{
6427 APIRET rc;
6428 ULONG values[QSV_MAX+1];
6429 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006430 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006431
6432 Py_BEGIN_ALLOW_THREADS
6433 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6434 Py_END_ALLOW_THREADS
6435
6436 if (rc != NO_ERROR) {
6437 os2_error(rc);
6438 return -1;
6439 }
6440
6441 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6442 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
6443 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6444 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6445 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6446 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
6447 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
6448
6449 switch (values[QSV_VERSION_MINOR]) {
6450 case 0: ver = "2.00"; break;
6451 case 10: ver = "2.10"; break;
6452 case 11: ver = "2.11"; break;
6453 case 30: ver = "3.00"; break;
6454 case 40: ver = "4.00"; break;
6455 case 50: ver = "5.00"; break;
6456 default:
Tim Peters885d4572001-11-28 20:27:42 +00006457 PyOS_snprintf(tmp, sizeof(tmp),
6458 "%d-%d", values[QSV_VERSION_MAJOR],
6459 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006460 ver = &tmp[0];
6461 }
6462
6463 /* Add Indicator of the Version of the Operating System */
6464 v = PyString_FromString(ver);
6465 if (!v || PyDict_SetItemString(d, "version", v) < 0)
6466 return -1;
6467 Py_DECREF(v);
6468
6469 /* Add Indicator of Which Drive was Used to Boot the System */
6470 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6471 tmp[1] = ':';
6472 tmp[2] = '\0';
6473
6474 v = PyString_FromString(tmp);
6475 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
6476 return -1;
6477 Py_DECREF(v);
6478
6479 return 0;
6480}
6481#endif
6482
Barry Warsaw4a342091996-12-19 23:50:02 +00006483static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006484all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006485{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006486#ifdef F_OK
6487 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006488#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006489#ifdef R_OK
6490 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006491#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006492#ifdef W_OK
6493 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006494#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006495#ifdef X_OK
6496 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006497#endif
Fred Drakec9680921999-12-13 16:37:25 +00006498#ifdef NGROUPS_MAX
6499 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6500#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006501#ifdef TMP_MAX
6502 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6503#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006504#ifdef WNOHANG
6505 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006506#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006507#ifdef O_RDONLY
6508 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6509#endif
6510#ifdef O_WRONLY
6511 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6512#endif
6513#ifdef O_RDWR
6514 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6515#endif
6516#ifdef O_NDELAY
6517 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6518#endif
6519#ifdef O_NONBLOCK
6520 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6521#endif
6522#ifdef O_APPEND
6523 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6524#endif
6525#ifdef O_DSYNC
6526 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6527#endif
6528#ifdef O_RSYNC
6529 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6530#endif
6531#ifdef O_SYNC
6532 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6533#endif
6534#ifdef O_NOCTTY
6535 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6536#endif
6537#ifdef O_CREAT
6538 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6539#endif
6540#ifdef O_EXCL
6541 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6542#endif
6543#ifdef O_TRUNC
6544 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6545#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006546#ifdef O_BINARY
6547 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6548#endif
6549#ifdef O_TEXT
6550 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6551#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006552#ifdef O_LARGEFILE
6553 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6554#endif
6555
Tim Peters5aa91602002-01-30 05:46:57 +00006556/* MS Windows */
6557#ifdef O_NOINHERIT
6558 /* Don't inherit in child processes. */
6559 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6560#endif
6561#ifdef _O_SHORT_LIVED
6562 /* Optimize for short life (keep in memory). */
6563 /* MS forgot to define this one with a non-underscore form too. */
6564 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6565#endif
6566#ifdef O_TEMPORARY
6567 /* Automatically delete when last handle is closed. */
6568 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6569#endif
6570#ifdef O_RANDOM
6571 /* Optimize for random access. */
6572 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6573#endif
6574#ifdef O_SEQUENTIAL
6575 /* Optimize for sequential access. */
6576 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6577#endif
6578
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006579/* GNU extensions. */
6580#ifdef O_DIRECT
6581 /* Direct disk access. */
6582 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6583#endif
6584#ifdef O_DIRECTORY
6585 /* Must be a directory. */
6586 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6587#endif
6588#ifdef O_NOFOLLOW
6589 /* Do not follow links. */
6590 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6591#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006592
Guido van Rossum246bc171999-02-01 23:54:31 +00006593#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006594#if defined(PYOS_OS2) && defined(PYCC_GCC)
6595 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6596 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6597 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6598 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6599 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6600 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6601 if (ins(d, "P_PM", (long)P_PM)) return -1;
6602 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6603 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6604 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6605 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6606 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6607 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6608 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6609 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6610 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6611 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6612 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6613 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6614 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6615#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006616 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6617 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6618 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6619 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6620 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006621#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006622#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006623
Guido van Rossumd48f2521997-12-05 22:19:34 +00006624#if defined(PYOS_OS2)
6625 if (insertvalues(d)) return -1;
6626#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006627 return 0;
6628}
6629
6630
Tim Peters5aa91602002-01-30 05:46:57 +00006631#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006632#define INITFUNC initnt
6633#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006634
6635#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006636#define INITFUNC initos2
6637#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006638
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006639#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006640#define INITFUNC initposix
6641#define MODNAME "posix"
6642#endif
6643
Guido van Rossum3886bb61998-12-04 18:50:17 +00006644DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006645INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006646{
Barry Warsaw53699e91996-12-10 23:23:01 +00006647 PyObject *m, *d, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006648
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006649 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006650 posix_methods,
6651 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006652 (PyObject *)NULL,
6653 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00006654 d = PyModule_GetDict(m);
Tim Peters5aa91602002-01-30 05:46:57 +00006655
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006656 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006657 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00006658 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006659 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006660 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006661
Barry Warsaw4a342091996-12-19 23:50:02 +00006662 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00006663 return;
6664
Fred Drakebec628d1999-12-15 18:31:10 +00006665 if (setup_confname_tables(d))
6666 return;
6667
Barry Warsawca74da41999-02-09 19:31:45 +00006668 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006669
Guido van Rossumb3d39562000-01-31 18:41:26 +00006670#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006671 if (posix_putenv_garbage == NULL)
6672 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006673#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006674
Guido van Rossum14648392001-12-08 18:02:58 +00006675 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006676 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
6677 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
6678
Guido van Rossum14648392001-12-08 18:02:58 +00006679 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006680 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Guido van Rossumbb2501f2001-12-27 16:23:28 +00006681 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006682}