blob: 46e145f484c66867c7ac2a7a22a75cf538d4a7ce [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);
Tim Peters75cdad52001-11-28 22:07:30 +00003288 PyOS_snprintf(
3289 s2, x,
Mark Hammond08501372001-01-31 07:30:29 +00003290 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003291 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003292 s1,
3293 s3,
3294 cmdstring);
3295 }
3296 }
3297
3298 /* Could be an else here to try cmd.exe / command.com in the path
3299 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003300 else {
Tim Peters402d5982001-08-27 06:37:48 +00003301 PyErr_SetString(PyExc_RuntimeError,
3302 "Cannot locate a COMSPEC environment variable to "
3303 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003304 return FALSE;
3305 }
Tim Peters5aa91602002-01-30 05:46:57 +00003306
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003307 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3308 siStartInfo.cb = sizeof(STARTUPINFO);
3309 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3310 siStartInfo.hStdInput = hStdin;
3311 siStartInfo.hStdOutput = hStdout;
3312 siStartInfo.hStdError = hStderr;
3313 siStartInfo.wShowWindow = SW_HIDE;
3314
3315 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003316 s2,
3317 NULL,
3318 NULL,
3319 TRUE,
3320 CREATE_NEW_CONSOLE,
3321 NULL,
3322 NULL,
3323 &siStartInfo,
3324 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003325 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003326 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003327
Mark Hammondb37a3732000-08-14 04:47:33 +00003328 /* Return process handle */
3329 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003330 return TRUE;
3331 }
Tim Peters402d5982001-08-27 06:37:48 +00003332 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003333 return FALSE;
3334}
3335
3336/* The following code is based off of KB: Q190351 */
3337
3338static PyObject *
3339_PyPopen(char *cmdstring, int mode, int n)
3340{
3341 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3342 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003343 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003344
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003345 SECURITY_ATTRIBUTES saAttr;
3346 BOOL fSuccess;
3347 int fd1, fd2, fd3;
3348 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003349 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003350 PyObject *f;
3351
3352 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3353 saAttr.bInheritHandle = TRUE;
3354 saAttr.lpSecurityDescriptor = NULL;
3355
3356 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3357 return win32_error("CreatePipe", NULL);
3358
3359 /* Create new output read handle and the input write handle. Set
3360 * the inheritance properties to FALSE. Otherwise, the child inherits
3361 * the these handles; resulting in non-closeable handles to the pipes
3362 * being created. */
3363 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003364 GetCurrentProcess(), &hChildStdinWrDup, 0,
3365 FALSE,
3366 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003367 if (!fSuccess)
3368 return win32_error("DuplicateHandle", NULL);
3369
3370 /* Close the inheritable version of ChildStdin
3371 that we're using. */
3372 CloseHandle(hChildStdinWr);
3373
3374 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3375 return win32_error("CreatePipe", NULL);
3376
3377 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003378 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3379 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003380 if (!fSuccess)
3381 return win32_error("DuplicateHandle", NULL);
3382
3383 /* Close the inheritable version of ChildStdout
3384 that we're using. */
3385 CloseHandle(hChildStdoutRd);
3386
3387 if (n != POPEN_4) {
3388 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3389 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003390 fSuccess = DuplicateHandle(GetCurrentProcess(),
3391 hChildStderrRd,
3392 GetCurrentProcess(),
3393 &hChildStderrRdDup, 0,
3394 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003395 if (!fSuccess)
3396 return win32_error("DuplicateHandle", NULL);
3397 /* Close the inheritable version of ChildStdErr that we're using. */
3398 CloseHandle(hChildStderrRd);
3399 }
Tim Peters5aa91602002-01-30 05:46:57 +00003400
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003401 switch (n) {
3402 case POPEN_1:
3403 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3404 case _O_WRONLY | _O_TEXT:
3405 /* Case for writing to child Stdin in text mode. */
3406 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3407 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003408 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003409 PyFile_SetBufSize(f, 0);
3410 /* We don't care about these pipes anymore, so close them. */
3411 CloseHandle(hChildStdoutRdDup);
3412 CloseHandle(hChildStderrRdDup);
3413 break;
3414
3415 case _O_RDONLY | _O_TEXT:
3416 /* Case for reading from child Stdout in text mode. */
3417 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3418 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003419 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003420 PyFile_SetBufSize(f, 0);
3421 /* We don't care about these pipes anymore, so close them. */
3422 CloseHandle(hChildStdinWrDup);
3423 CloseHandle(hChildStderrRdDup);
3424 break;
3425
3426 case _O_RDONLY | _O_BINARY:
3427 /* Case for readinig from child Stdout in binary mode. */
3428 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3429 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003430 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003431 PyFile_SetBufSize(f, 0);
3432 /* We don't care about these pipes anymore, so close them. */
3433 CloseHandle(hChildStdinWrDup);
3434 CloseHandle(hChildStderrRdDup);
3435 break;
3436
3437 case _O_WRONLY | _O_BINARY:
3438 /* Case for writing to child Stdin in binary mode. */
3439 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3440 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003441 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003442 PyFile_SetBufSize(f, 0);
3443 /* We don't care about these pipes anymore, so close them. */
3444 CloseHandle(hChildStdoutRdDup);
3445 CloseHandle(hChildStderrRdDup);
3446 break;
3447 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003448 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003449 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003450
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003451 case POPEN_2:
3452 case POPEN_4:
3453 {
3454 char *m1, *m2;
3455 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003456
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003457 if (mode && _O_TEXT) {
3458 m1 = "r";
3459 m2 = "w";
3460 } else {
3461 m1 = "rb";
3462 m2 = "wb";
3463 }
3464
3465 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3466 f1 = _fdopen(fd1, m2);
3467 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3468 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003469 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003470 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003471 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003472 PyFile_SetBufSize(p2, 0);
3473
3474 if (n != 4)
3475 CloseHandle(hChildStderrRdDup);
3476
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003477 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003478 Py_XDECREF(p1);
3479 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003480 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003481 break;
3482 }
Tim Peters5aa91602002-01-30 05:46:57 +00003483
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003484 case POPEN_3:
3485 {
3486 char *m1, *m2;
3487 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003488
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003489 if (mode && _O_TEXT) {
3490 m1 = "r";
3491 m2 = "w";
3492 } else {
3493 m1 = "rb";
3494 m2 = "wb";
3495 }
3496
3497 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3498 f1 = _fdopen(fd1, m2);
3499 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3500 f2 = _fdopen(fd2, m1);
3501 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3502 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003503 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003504 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3505 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003506 PyFile_SetBufSize(p1, 0);
3507 PyFile_SetBufSize(p2, 0);
3508 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003509 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003510 Py_XDECREF(p1);
3511 Py_XDECREF(p2);
3512 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003513 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003514 break;
3515 }
3516 }
3517
3518 if (n == POPEN_4) {
3519 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003520 hChildStdinRd,
3521 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003522 hChildStdoutWr,
3523 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003524 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003525 }
3526 else {
3527 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003528 hChildStdinRd,
3529 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003530 hChildStderrWr,
3531 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003532 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003533 }
3534
Mark Hammondb37a3732000-08-14 04:47:33 +00003535 /*
3536 * Insert the files we've created into the process dictionary
3537 * all referencing the list with the process handle and the
3538 * initial number of files (see description below in _PyPclose).
3539 * Since if _PyPclose later tried to wait on a process when all
3540 * handles weren't closed, it could create a deadlock with the
3541 * child, we spend some energy here to try to ensure that we
3542 * either insert all file handles into the dictionary or none
3543 * at all. It's a little clumsy with the various popen modes
3544 * and variable number of files involved.
3545 */
3546 if (!_PyPopenProcs) {
3547 _PyPopenProcs = PyDict_New();
3548 }
3549
3550 if (_PyPopenProcs) {
3551 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3552 int ins_rc[3];
3553
3554 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3555 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3556
3557 procObj = PyList_New(2);
3558 hProcessObj = PyLong_FromVoidPtr(hProcess);
3559 intObj = PyInt_FromLong(file_count);
3560
3561 if (procObj && hProcessObj && intObj) {
3562 PyList_SetItem(procObj,0,hProcessObj);
3563 PyList_SetItem(procObj,1,intObj);
3564
3565 fileObj[0] = PyLong_FromVoidPtr(f1);
3566 if (fileObj[0]) {
3567 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3568 fileObj[0],
3569 procObj);
3570 }
3571 if (file_count >= 2) {
3572 fileObj[1] = PyLong_FromVoidPtr(f2);
3573 if (fileObj[1]) {
3574 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3575 fileObj[1],
3576 procObj);
3577 }
3578 }
3579 if (file_count >= 3) {
3580 fileObj[2] = PyLong_FromVoidPtr(f3);
3581 if (fileObj[2]) {
3582 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3583 fileObj[2],
3584 procObj);
3585 }
3586 }
3587
3588 if (ins_rc[0] < 0 || !fileObj[0] ||
3589 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3590 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3591 /* Something failed - remove any dictionary
3592 * entries that did make it.
3593 */
3594 if (!ins_rc[0] && fileObj[0]) {
3595 PyDict_DelItem(_PyPopenProcs,
3596 fileObj[0]);
3597 }
3598 if (!ins_rc[1] && fileObj[1]) {
3599 PyDict_DelItem(_PyPopenProcs,
3600 fileObj[1]);
3601 }
3602 if (!ins_rc[2] && fileObj[2]) {
3603 PyDict_DelItem(_PyPopenProcs,
3604 fileObj[2]);
3605 }
3606 }
3607 }
Tim Peters5aa91602002-01-30 05:46:57 +00003608
Mark Hammondb37a3732000-08-14 04:47:33 +00003609 /*
3610 * Clean up our localized references for the dictionary keys
3611 * and value since PyDict_SetItem will Py_INCREF any copies
3612 * that got placed in the dictionary.
3613 */
3614 Py_XDECREF(procObj);
3615 Py_XDECREF(fileObj[0]);
3616 Py_XDECREF(fileObj[1]);
3617 Py_XDECREF(fileObj[2]);
3618 }
3619
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003620 /* Child is launched. Close the parents copy of those pipe
3621 * handles that only the child should have open. You need to
3622 * make sure that no handles to the write end of the output pipe
3623 * are maintained in this process or else the pipe will not close
3624 * when the child process exits and the ReadFile will hang. */
3625
3626 if (!CloseHandle(hChildStdinRd))
3627 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003628
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003629 if (!CloseHandle(hChildStdoutWr))
3630 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003631
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003632 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3633 return win32_error("CloseHandle", NULL);
3634
3635 return f;
3636}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003637
3638/*
3639 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3640 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003641 *
3642 * This function uses the _PyPopenProcs dictionary in order to map the
3643 * input file pointer to information about the process that was
3644 * originally created by the popen* call that created the file pointer.
3645 * The dictionary uses the file pointer as a key (with one entry
3646 * inserted for each file returned by the original popen* call) and a
3647 * single list object as the value for all files from a single call.
3648 * The list object contains the Win32 process handle at [0], and a file
3649 * count at [1], which is initialized to the total number of file
3650 * handles using that list.
3651 *
3652 * This function closes whichever handle it is passed, and decrements
3653 * the file count in the dictionary for the process handle pointed to
3654 * by this file. On the last close (when the file count reaches zero),
3655 * this function will wait for the child process and then return its
3656 * exit code as the result of the close() operation. This permits the
3657 * files to be closed in any order - it is always the close() of the
3658 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003659 */
Tim Peters736aa322000-09-01 06:51:24 +00003660
3661 /* RED_FLAG 31-Aug-2000 Tim
3662 * This is always called (today!) between a pair of
3663 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3664 * macros. So the thread running this has no valid thread state, as
3665 * far as Python is concerned. However, this calls some Python API
3666 * functions that cannot be called safely without a valid thread
3667 * state, in particular PyDict_GetItem.
3668 * As a temporary hack (although it may last for years ...), we
3669 * *rely* on not having a valid thread state in this function, in
3670 * order to create our own "from scratch".
3671 * This will deadlock if _PyPclose is ever called by a thread
3672 * holding the global lock.
3673 */
3674
Fredrik Lundh56055a42000-07-23 19:47:12 +00003675static int _PyPclose(FILE *file)
3676{
Fredrik Lundh20318932000-07-26 17:29:12 +00003677 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003678 DWORD exit_code;
3679 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003680 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3681 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003682#ifdef WITH_THREAD
3683 PyInterpreterState* pInterpreterState;
3684 PyThreadState* pThreadState;
3685#endif
3686
Fredrik Lundh20318932000-07-26 17:29:12 +00003687 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003688 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003689 */
3690 result = fclose(file);
3691
Tim Peters736aa322000-09-01 06:51:24 +00003692#ifdef WITH_THREAD
3693 /* Bootstrap a valid thread state into existence. */
3694 pInterpreterState = PyInterpreterState_New();
3695 if (!pInterpreterState) {
3696 /* Well, we're hosed now! We don't have a thread
3697 * state, so can't call a nice error routine, or raise
3698 * an exception. Just die.
3699 */
3700 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003701 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003702 return -1; /* unreachable */
3703 }
3704 pThreadState = PyThreadState_New(pInterpreterState);
3705 if (!pThreadState) {
3706 Py_FatalError("unable to allocate thread 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 /* Grab the global lock. Note that this will deadlock if the
3711 * current thread already has the lock! (see RED_FLAG comments
3712 * before this function)
3713 */
3714 PyEval_RestoreThread(pThreadState);
3715#endif
3716
Fredrik Lundh56055a42000-07-23 19:47:12 +00003717 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003718 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3719 (procObj = PyDict_GetItem(_PyPopenProcs,
3720 fileObj)) != NULL &&
3721 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3722 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3723
3724 hProcess = PyLong_AsVoidPtr(hProcessObj);
3725 file_count = PyInt_AsLong(intObj);
3726
3727 if (file_count > 1) {
3728 /* Still other files referencing process */
3729 file_count--;
3730 PyList_SetItem(procObj,1,
3731 PyInt_FromLong(file_count));
3732 } else {
3733 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003734 if (result != EOF &&
3735 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3736 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003737 /* Possible truncation here in 16-bit environments, but
3738 * real exit codes are just the lower byte in any event.
3739 */
3740 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003741 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003742 /* Indicate failure - this will cause the file object
3743 * to raise an I/O error and translate the last Win32
3744 * error code from errno. We do have a problem with
3745 * last errors that overlap the normal errno table,
3746 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003747 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003748 if (result != EOF) {
3749 /* If the error wasn't from the fclose(), then
3750 * set errno for the file object error handling.
3751 */
3752 errno = GetLastError();
3753 }
3754 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003755 }
3756
3757 /* Free up the native handle at this point */
3758 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003759 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003760
Mark Hammondb37a3732000-08-14 04:47:33 +00003761 /* Remove this file pointer from dictionary */
3762 PyDict_DelItem(_PyPopenProcs, fileObj);
3763
3764 if (PyDict_Size(_PyPopenProcs) == 0) {
3765 Py_DECREF(_PyPopenProcs);
3766 _PyPopenProcs = NULL;
3767 }
3768
3769 } /* if object retrieval ok */
3770
3771 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003772 } /* if _PyPopenProcs */
3773
Tim Peters736aa322000-09-01 06:51:24 +00003774#ifdef WITH_THREAD
3775 /* Tear down the thread & interpreter states.
3776 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003777 * call the thread clear & delete functions, and indeed insist on
3778 * doing that themselves. The lock must be held during the clear, but
3779 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003780 */
3781 PyInterpreterState_Clear(pInterpreterState);
3782 PyEval_ReleaseThread(pThreadState);
3783 PyInterpreterState_Delete(pInterpreterState);
3784#endif
3785
Fredrik Lundh56055a42000-07-23 19:47:12 +00003786 return result;
3787}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003788
3789#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003791posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003792{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003793 char *name;
3794 char *mode = "r";
3795 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003796 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003797 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003798 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003799 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003800 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003801 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003802 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003803 if (fp == NULL)
3804 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003805 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003806 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003807 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003808 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003809}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003810
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003811#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003812#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003813
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003814
Guido van Rossumb6775db1994-08-01 11:34:53 +00003815#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003816static char posix_setuid__doc__[] =
3817"setuid(uid) -> None\n\
3818Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003820posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003821{
3822 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003823 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003824 return NULL;
3825 if (setuid(uid) < 0)
3826 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003827 Py_INCREF(Py_None);
3828 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003829}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003830#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003831
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003832
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003833#ifdef HAVE_SETEUID
3834static char posix_seteuid__doc__[] =
3835"seteuid(uid) -> None\n\
3836Set the current process's effective user id.";
3837static PyObject *
3838posix_seteuid (PyObject *self, PyObject *args)
3839{
3840 int euid;
3841 if (!PyArg_ParseTuple(args, "i", &euid)) {
3842 return NULL;
3843 } else if (seteuid(euid) < 0) {
3844 return posix_error();
3845 } else {
3846 Py_INCREF(Py_None);
3847 return Py_None;
3848 }
3849}
3850#endif /* HAVE_SETEUID */
3851
3852#ifdef HAVE_SETEGID
3853static char posix_setegid__doc__[] =
3854"setegid(gid) -> None\n\
3855Set the current process's effective group id.";
3856static PyObject *
3857posix_setegid (PyObject *self, PyObject *args)
3858{
3859 int egid;
3860 if (!PyArg_ParseTuple(args, "i", &egid)) {
3861 return NULL;
3862 } else if (setegid(egid) < 0) {
3863 return posix_error();
3864 } else {
3865 Py_INCREF(Py_None);
3866 return Py_None;
3867 }
3868}
3869#endif /* HAVE_SETEGID */
3870
3871#ifdef HAVE_SETREUID
3872static char posix_setreuid__doc__[] =
3873"seteuid(ruid, euid) -> None\n\
3874Set the current process's real and effective user ids.";
3875static PyObject *
3876posix_setreuid (PyObject *self, PyObject *args)
3877{
3878 int ruid, euid;
3879 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3880 return NULL;
3881 } else if (setreuid(ruid, euid) < 0) {
3882 return posix_error();
3883 } else {
3884 Py_INCREF(Py_None);
3885 return Py_None;
3886 }
3887}
3888#endif /* HAVE_SETREUID */
3889
3890#ifdef HAVE_SETREGID
3891static char posix_setregid__doc__[] =
3892"setegid(rgid, egid) -> None\n\
3893Set the current process's real and effective group ids.";
3894static PyObject *
3895posix_setregid (PyObject *self, PyObject *args)
3896{
3897 int rgid, egid;
3898 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3899 return NULL;
3900 } else if (setregid(rgid, egid) < 0) {
3901 return posix_error();
3902 } else {
3903 Py_INCREF(Py_None);
3904 return Py_None;
3905 }
3906}
3907#endif /* HAVE_SETREGID */
3908
Guido van Rossumb6775db1994-08-01 11:34:53 +00003909#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003910static char posix_setgid__doc__[] =
3911"setgid(gid) -> None\n\
3912Set the current process's group id.";
3913
Barry Warsaw53699e91996-12-10 23:23:01 +00003914static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003915posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003916{
3917 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003918 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003919 return NULL;
3920 if (setgid(gid) < 0)
3921 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003922 Py_INCREF(Py_None);
3923 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003924}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003925#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003926
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003927#ifdef HAVE_SETGROUPS
3928static char posix_setgroups__doc__[] =
3929"setgroups(list) -> None\n\
3930Set the groups of the current process to list.";
3931
3932static PyObject *
3933posix_setgroups(PyObject *self, PyObject *args)
3934{
3935 PyObject *groups;
3936 int i, len;
3937 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003938
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003939 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3940 return NULL;
3941 if (!PySequence_Check(groups)) {
3942 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3943 return NULL;
3944 }
3945 len = PySequence_Size(groups);
3946 if (len > MAX_GROUPS) {
3947 PyErr_SetString(PyExc_ValueError, "too many groups");
3948 return NULL;
3949 }
3950 for(i = 0; i < len; i++) {
3951 PyObject *elem;
3952 elem = PySequence_GetItem(groups, i);
3953 if (!elem)
3954 return NULL;
3955 if (!PyInt_Check(elem)) {
3956 PyErr_SetString(PyExc_TypeError,
3957 "groups must be integers");
3958 Py_DECREF(elem);
3959 return NULL;
3960 }
3961 /* XXX: check that value fits into gid_t. */
3962 grouplist[i] = PyInt_AsLong(elem);
3963 Py_DECREF(elem);
3964 }
3965
3966 if (setgroups(len, grouplist) < 0)
3967 return posix_error();
3968 Py_INCREF(Py_None);
3969 return Py_None;
3970}
3971#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003972
Guido van Rossumb6775db1994-08-01 11:34:53 +00003973#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003974static char posix_waitpid__doc__[] =
3975"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003976Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003977
Barry Warsaw53699e91996-12-10 23:23:01 +00003978static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003979posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003980{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003981 int pid, options;
3982#ifdef UNION_WAIT
3983 union wait status;
3984#define status_i (status.w_status)
3985#else
3986 int status;
3987#define status_i status
3988#endif
3989 status_i = 0;
3990
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003991 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003992 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003993 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003994 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00003995 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003996 if (pid == -1)
3997 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003998 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003999 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004000}
4001
Tim Petersab034fa2002-02-01 11:27:43 +00004002#elif defined(HAVE_CWAIT)
4003
4004/* MS C has a variant of waitpid() that's usable for most purposes. */
4005static char posix_waitpid__doc__[] =
4006"waitpid(pid, options) -> (pid, status << 8)\n"
4007"Wait for completion of a given process. options is ignored on Windows.";
4008
4009static PyObject *
4010posix_waitpid(PyObject *self, PyObject *args)
4011{
4012 int pid, options;
4013 int status;
4014
4015 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4016 return NULL;
4017 Py_BEGIN_ALLOW_THREADS
4018 pid = _cwait(&status, pid, options);
4019 Py_END_ALLOW_THREADS
4020 if (pid == -1)
4021 return posix_error();
4022 else
4023 /* shift the status left a byte so this is more like the
4024 POSIX waitpid */
4025 return Py_BuildValue("ii", pid, status << 8);
4026}
4027#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004028
Guido van Rossumad0ee831995-03-01 10:34:45 +00004029#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004030static char posix_wait__doc__[] =
4031"wait() -> (pid, status)\n\
4032Wait for completion of a child process.";
4033
Barry Warsaw53699e91996-12-10 23:23:01 +00004034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004035posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004036{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004037 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004038#ifdef UNION_WAIT
4039 union wait status;
4040#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004041#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004042 int status;
4043#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004044#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004045 if (!PyArg_ParseTuple(args, ":wait"))
4046 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004047 status_i = 0;
4048 Py_BEGIN_ALLOW_THREADS
4049 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004050 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004051 if (pid == -1)
4052 return posix_error();
4053 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004054 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004055#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004056}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004057#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004059
4060static char posix_lstat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00004061"lstat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
4062 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004063Like stat(path), but do not follow symbolic links.";
4064
Barry Warsaw53699e91996-12-10 23:23:01 +00004065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004066posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004067{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004068#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004069 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004070#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004071 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004072#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004073}
4074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004075
Guido van Rossumb6775db1994-08-01 11:34:53 +00004076#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004077static char posix_readlink__doc__[] =
4078"readlink(path) -> path\n\
4079Return a string representing the path to which the symbolic link points.";
4080
Barry Warsaw53699e91996-12-10 23:23:01 +00004081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004082posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004083{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004084 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004085 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004086 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004087 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004088 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004089 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004090 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004091 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004092 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004093 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004094 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004095}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004096#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004098
Guido van Rossumb6775db1994-08-01 11:34:53 +00004099#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004100static char posix_symlink__doc__[] =
4101"symlink(src, dst) -> None\n\
4102Create a symbolic link.";
4103
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004104static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004105posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004106{
Mark Hammondef8b6542001-05-13 08:04:26 +00004107 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004108}
4109#endif /* HAVE_SYMLINK */
4110
4111
4112#ifdef HAVE_TIMES
4113#ifndef HZ
4114#define HZ 60 /* Universal constant :-) */
4115#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004116
Guido van Rossumd48f2521997-12-05 22:19:34 +00004117#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4118static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004119system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004120{
4121 ULONG value = 0;
4122
4123 Py_BEGIN_ALLOW_THREADS
4124 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4125 Py_END_ALLOW_THREADS
4126
4127 return value;
4128}
4129
4130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004131posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004132{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004133 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004134 return NULL;
4135
4136 /* Currently Only Uptime is Provided -- Others Later */
4137 return Py_BuildValue("ddddd",
4138 (double)0 /* t.tms_utime / HZ */,
4139 (double)0 /* t.tms_stime / HZ */,
4140 (double)0 /* t.tms_cutime / HZ */,
4141 (double)0 /* t.tms_cstime / HZ */,
4142 (double)system_uptime() / 1000);
4143}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004144#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004146posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004147{
4148 struct tms t;
4149 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004150 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004151 return NULL;
4152 errno = 0;
4153 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004154 if (c == (clock_t) -1)
4155 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004156 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004157 (double)t.tms_utime / HZ,
4158 (double)t.tms_stime / HZ,
4159 (double)t.tms_cutime / HZ,
4160 (double)t.tms_cstime / HZ,
4161 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004162}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004163#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004164#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004165
4166
Guido van Rossum87755a21996-09-07 00:59:43 +00004167#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004168#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004170posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004171{
4172 FILETIME create, exit, kernel, user;
4173 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004174 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004175 return NULL;
4176 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004177 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4178 /* The fields of a FILETIME structure are the hi and lo part
4179 of a 64-bit value expressed in 100 nanosecond units.
4180 1e7 is one second in such units; 1e-7 the inverse.
4181 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4182 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004183 return Py_BuildValue(
4184 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004185 (double)(kernel.dwHighDateTime*429.4967296 +
4186 kernel.dwLowDateTime*1e-7),
4187 (double)(user.dwHighDateTime*429.4967296 +
4188 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004189 (double)0,
4190 (double)0,
4191 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004192}
Guido van Rossum8d665e61996-06-26 18:22:49 +00004193#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004194
4195#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00004196static char posix_times__doc__[] =
4197"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
4198Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004199#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004201
Guido van Rossumb6775db1994-08-01 11:34:53 +00004202#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004203static char posix_setsid__doc__[] =
4204"setsid() -> None\n\
4205Call the system call setsid().";
4206
Barry Warsaw53699e91996-12-10 23:23:01 +00004207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004208posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004209{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004210 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004211 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004212 if (setsid() < 0)
4213 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004214 Py_INCREF(Py_None);
4215 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004216}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004217#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004218
Guido van Rossumb6775db1994-08-01 11:34:53 +00004219#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004220static char posix_setpgid__doc__[] =
4221"setpgid(pid, pgrp) -> None\n\
4222Call the system call setpgid().";
4223
Barry Warsaw53699e91996-12-10 23:23:01 +00004224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004225posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004226{
4227 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004228 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004229 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004230 if (setpgid(pid, pgrp) < 0)
4231 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004232 Py_INCREF(Py_None);
4233 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004234}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004235#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004236
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004237
Guido van Rossumb6775db1994-08-01 11:34:53 +00004238#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004239static char posix_tcgetpgrp__doc__[] =
4240"tcgetpgrp(fd) -> pgid\n\
4241Return the process group associated with the terminal given by a fd.";
4242
Barry Warsaw53699e91996-12-10 23:23:01 +00004243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004244posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004245{
4246 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004247 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004248 return NULL;
4249 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004250 if (pgid < 0)
4251 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004252 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004253}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004254#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004256
Guido van Rossumb6775db1994-08-01 11:34:53 +00004257#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004258static char posix_tcsetpgrp__doc__[] =
4259"tcsetpgrp(fd, pgid) -> None\n\
4260Set the process group associated with the terminal given by a fd.";
4261
Barry Warsaw53699e91996-12-10 23:23:01 +00004262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004263posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004264{
4265 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004266 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004267 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004268 if (tcsetpgrp(fd, pgid) < 0)
4269 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004270 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004271 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004272}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004273#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004274
Guido van Rossum687dd131993-05-17 08:34:16 +00004275/* Functions acting on file descriptors */
4276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004277static char posix_open__doc__[] =
4278"open(filename, flag [, mode=0777]) -> fd\n\
4279Open a file (for low level IO).";
4280
Barry Warsaw53699e91996-12-10 23:23:01 +00004281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004282posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004283{
Mark Hammondef8b6542001-05-13 08:04:26 +00004284 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004285 int flag;
4286 int mode = 0777;
4287 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004288 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004289 Py_FileSystemDefaultEncoding, &file,
4290 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004291 return NULL;
4292
Barry Warsaw53699e91996-12-10 23:23:01 +00004293 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004294 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004295 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004296 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004297 return posix_error_with_allocated_filename(file);
4298 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004299 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004300}
4301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004302
4303static char posix_close__doc__[] =
4304"close(fd) -> None\n\
4305Close a file descriptor (for low level IO).";
4306
Barry Warsaw53699e91996-12-10 23:23:01 +00004307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004308posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004309{
4310 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004311 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004312 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004313 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004314 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004315 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004316 if (res < 0)
4317 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004318 Py_INCREF(Py_None);
4319 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004320}
4321
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004322
4323static char posix_dup__doc__[] =
4324"dup(fd) -> fd2\n\
4325Return a duplicate of a file descriptor.";
4326
Barry Warsaw53699e91996-12-10 23:23:01 +00004327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004328posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004329{
4330 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004331 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004332 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004333 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004334 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004335 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004336 if (fd < 0)
4337 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004338 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004339}
4340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004341
4342static char posix_dup2__doc__[] =
4343"dup2(fd, fd2) -> None\n\
4344Duplicate file descriptor.";
4345
Barry Warsaw53699e91996-12-10 23:23:01 +00004346static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004347posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004348{
4349 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004350 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004351 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004352 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004353 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004354 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004355 if (res < 0)
4356 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004357 Py_INCREF(Py_None);
4358 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004359}
4360
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004361
4362static char posix_lseek__doc__[] =
4363"lseek(fd, pos, how) -> newpos\n\
4364Set the current position of a file descriptor.";
4365
Barry Warsaw53699e91996-12-10 23:23:01 +00004366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004367posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004368{
4369 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00004370#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004371 LONG_LONG pos, res;
4372#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004373 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004374#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004375 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004376 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004377 return NULL;
4378#ifdef SEEK_SET
4379 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4380 switch (how) {
4381 case 0: how = SEEK_SET; break;
4382 case 1: how = SEEK_CUR; break;
4383 case 2: how = SEEK_END; break;
4384 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004385#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004386
4387#if !defined(HAVE_LARGEFILE_SUPPORT)
4388 pos = PyInt_AsLong(posobj);
4389#else
4390 pos = PyLong_Check(posobj) ?
4391 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4392#endif
4393 if (PyErr_Occurred())
4394 return NULL;
4395
Barry Warsaw53699e91996-12-10 23:23:01 +00004396 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00004397#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004398 res = _lseeki64(fd, pos, how);
4399#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004400 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004401#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004402 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004403 if (res < 0)
4404 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004405
4406#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004407 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004408#else
4409 return PyLong_FromLongLong(res);
4410#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004411}
4412
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004413
4414static char posix_read__doc__[] =
4415"read(fd, buffersize) -> string\n\
4416Read a file descriptor.";
4417
Barry Warsaw53699e91996-12-10 23:23:01 +00004418static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004419posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004420{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004421 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004422 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004423 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004424 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004425 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004426 if (buffer == NULL)
4427 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004428 Py_BEGIN_ALLOW_THREADS
4429 n = read(fd, PyString_AsString(buffer), size);
4430 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004431 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004432 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004433 return posix_error();
4434 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004435 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004436 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004437 return buffer;
4438}
4439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004440
4441static char posix_write__doc__[] =
4442"write(fd, string) -> byteswritten\n\
4443Write a string to a file descriptor.";
4444
Barry Warsaw53699e91996-12-10 23:23:01 +00004445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004446posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004447{
4448 int fd, size;
4449 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004450 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004451 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004452 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004453 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004454 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004455 if (size < 0)
4456 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004457 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004458}
4459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004460
4461static char posix_fstat__doc__[]=
4462"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
4463Like stat(), but for an open file descriptor.";
4464
Barry Warsaw53699e91996-12-10 23:23:01 +00004465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004466posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004467{
4468 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004469 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004470 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004471 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004472 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004473 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004474 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004475 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004476 if (res != 0)
4477 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004478
Fred Drake699f3522000-06-29 21:12:41 +00004479 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004480}
4481
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004482
4483static char posix_fdopen__doc__[] =
4484"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
4485Return an open file object connected to a file descriptor.";
4486
Barry Warsaw53699e91996-12-10 23:23:01 +00004487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004488posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004489{
Guido van Rossum687dd131993-05-17 08:34:16 +00004490 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004491 char *mode = "r";
4492 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004493 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004494 PyObject *f;
4495 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004496 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004497
Barry Warsaw53699e91996-12-10 23:23:01 +00004498 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004499 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004500 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004501 if (fp == NULL)
4502 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004503 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004504 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004505 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004506 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004507}
4508
Skip Montanaro1517d842000-07-19 14:34:14 +00004509static char posix_isatty__doc__[] =
4510"isatty(fd) -> Boolean\n\
4511Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00004512connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00004513
4514static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004515posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004516{
4517 int fd;
4518 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4519 return NULL;
4520 return Py_BuildValue("i", isatty(fd));
4521}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004522
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004523#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004524static char posix_pipe__doc__[] =
4525"pipe() -> (read_end, write_end)\n\
4526Create a pipe.";
4527
Barry Warsaw53699e91996-12-10 23:23:01 +00004528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004529posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004530{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004531#if defined(PYOS_OS2)
4532 HFILE read, write;
4533 APIRET rc;
4534
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004535 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004536 return NULL;
4537
4538 Py_BEGIN_ALLOW_THREADS
4539 rc = DosCreatePipe( &read, &write, 4096);
4540 Py_END_ALLOW_THREADS
4541 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004542 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004543
4544 return Py_BuildValue("(ii)", read, write);
4545#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00004546#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00004547 int fds[2];
4548 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004549 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004550 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004551 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004552 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004553 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004554 if (res != 0)
4555 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004556 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004557#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00004558 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004559 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004560 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004561 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004562 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004563 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004564 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004565 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004566 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004567 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004568 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4569 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004570 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004571#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004572#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004573}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004574#endif /* HAVE_PIPE */
4575
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004576
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004577#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004578static char posix_mkfifo__doc__[] =
4579"mkfifo(file, [, mode=0666]) -> None\n\
4580Create a FIFO (a POSIX named pipe).";
4581
Barry Warsaw53699e91996-12-10 23:23:01 +00004582static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004583posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004584{
4585 char *file;
4586 int mode = 0666;
4587 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004588 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004589 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004590 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004591 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004592 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004593 if (res < 0)
4594 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004595 Py_INCREF(Py_None);
4596 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004597}
4598#endif
4599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004600
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004601#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004602static char posix_ftruncate__doc__[] =
4603"ftruncate(fd, length) -> None\n\
4604Truncate a file to a specified length.";
4605
Barry Warsaw53699e91996-12-10 23:23:01 +00004606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004607posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004608{
4609 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004610 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004611 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004612 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004613
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004614 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004615 return NULL;
4616
4617#if !defined(HAVE_LARGEFILE_SUPPORT)
4618 length = PyInt_AsLong(lenobj);
4619#else
4620 length = PyLong_Check(lenobj) ?
4621 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4622#endif
4623 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004624 return NULL;
4625
Barry Warsaw53699e91996-12-10 23:23:01 +00004626 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004627 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004628 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004629 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004630 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004631 return NULL;
4632 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004633 Py_INCREF(Py_None);
4634 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004635}
4636#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004637
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004638#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004639static char posix_putenv__doc__[] =
4640"putenv(key, value) -> None\n\
4641Change or add an environment variable.";
4642
Fred Drake762e2061999-08-26 17:23:54 +00004643/* Save putenv() parameters as values here, so we can collect them when they
4644 * get re-set with another call for the same key. */
4645static PyObject *posix_putenv_garbage;
4646
Tim Peters5aa91602002-01-30 05:46:57 +00004647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004648posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004649{
4650 char *s1, *s2;
4651 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004652 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004653 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004654
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004655 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004656 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004657
4658#if defined(PYOS_OS2)
4659 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4660 APIRET rc;
4661
4662 if (strlen(s2) == 0) /* If New Value is an Empty String */
4663 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4664
4665 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4666 if (rc != NO_ERROR)
4667 return os2_error(rc);
4668
4669 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4670 APIRET rc;
4671
4672 if (strlen(s2) == 0) /* If New Value is an Empty String */
4673 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4674
4675 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4676 if (rc != NO_ERROR)
4677 return os2_error(rc);
4678 } else {
4679#endif
4680
Fred Drake762e2061999-08-26 17:23:54 +00004681 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004682 len = strlen(s1) + strlen(s2) + 2;
4683 /* len includes space for a trailing \0; the size arg to
4684 PyString_FromStringAndSize does not count that */
4685 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004686 if (newstr == NULL)
4687 return PyErr_NoMemory();
4688 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004689 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004690 if (putenv(new)) {
4691 posix_error();
4692 return NULL;
4693 }
Fred Drake762e2061999-08-26 17:23:54 +00004694 /* Install the first arg and newstr in posix_putenv_garbage;
4695 * this will cause previous value to be collected. This has to
4696 * happen after the real putenv() call because the old value
4697 * was still accessible until then. */
4698 if (PyDict_SetItem(posix_putenv_garbage,
4699 PyTuple_GET_ITEM(args, 0), newstr)) {
4700 /* really not much we can do; just leak */
4701 PyErr_Clear();
4702 }
4703 else {
4704 Py_DECREF(newstr);
4705 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004706
4707#if defined(PYOS_OS2)
4708 }
4709#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004710 Py_INCREF(Py_None);
4711 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004712}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004713#endif /* putenv */
4714
Guido van Rossumc524d952001-10-19 01:31:59 +00004715#ifdef HAVE_UNSETENV
4716static char posix_unsetenv__doc__[] =
4717"unsetenv(key) -> None\n\
4718Delete an environment variable.";
4719
4720static PyObject *
4721posix_unsetenv(PyObject *self, PyObject *args)
4722{
4723 char *s1;
4724
4725 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4726 return NULL;
4727
4728 unsetenv(s1);
4729
4730 /* Remove the key from posix_putenv_garbage;
4731 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004732 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004733 * old value was still accessible until then.
4734 */
4735 if (PyDict_DelItem(posix_putenv_garbage,
4736 PyTuple_GET_ITEM(args, 0))) {
4737 /* really not much we can do; just leak */
4738 PyErr_Clear();
4739 }
4740
4741 Py_INCREF(Py_None);
4742 return Py_None;
4743}
4744#endif /* unsetenv */
4745
Guido van Rossumb6a47161997-09-15 22:54:34 +00004746#ifdef HAVE_STRERROR
4747static char posix_strerror__doc__[] =
4748"strerror(code) -> string\n\
4749Translate an error code to a message string.";
4750
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004751static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004752posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004753{
4754 int code;
4755 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004756 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004757 return NULL;
4758 message = strerror(code);
4759 if (message == NULL) {
4760 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004761 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004762 return NULL;
4763 }
4764 return PyString_FromString(message);
4765}
4766#endif /* strerror */
4767
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004768
Guido van Rossumc9641791998-08-04 15:26:23 +00004769#ifdef HAVE_SYS_WAIT_H
4770
4771#ifdef WIFSTOPPED
4772static char posix_WIFSTOPPED__doc__[] =
4773"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004774Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004775
4776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004777posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004778{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004779#ifdef UNION_WAIT
4780 union wait status;
4781#define status_i (status.w_status)
4782#else
4783 int status;
4784#define status_i status
4785#endif
4786 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004787
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004788 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004789 {
4790 return NULL;
4791 }
Tim Peters5aa91602002-01-30 05:46:57 +00004792
Guido van Rossumc9641791998-08-04 15:26:23 +00004793 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004794#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004795}
4796#endif /* WIFSTOPPED */
4797
4798#ifdef WIFSIGNALED
4799static char posix_WIFSIGNALED__doc__[] =
4800"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004801Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004802
4803static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004804posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004805{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004806#ifdef UNION_WAIT
4807 union wait status;
4808#define status_i (status.w_status)
4809#else
4810 int status;
4811#define status_i status
4812#endif
4813 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004814
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004815 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004816 {
4817 return NULL;
4818 }
Tim Peters5aa91602002-01-30 05:46:57 +00004819
Guido van Rossumc9641791998-08-04 15:26:23 +00004820 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004821#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004822}
4823#endif /* WIFSIGNALED */
4824
4825#ifdef WIFEXITED
4826static char posix_WIFEXITED__doc__[] =
4827"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004828Return true if the process returning 'status' exited using the exit()\n\
4829system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004830
4831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004832posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004833{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004834#ifdef UNION_WAIT
4835 union wait status;
4836#define status_i (status.w_status)
4837#else
4838 int status;
4839#define status_i status
4840#endif
4841 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004842
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004843 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004844 {
4845 return NULL;
4846 }
Tim Peters5aa91602002-01-30 05:46:57 +00004847
Guido van Rossumc9641791998-08-04 15:26:23 +00004848 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004849#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004850}
4851#endif /* WIFEXITED */
4852
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004853#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004854static char posix_WEXITSTATUS__doc__[] =
4855"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004856Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004857
4858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004859posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004860{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004861#ifdef UNION_WAIT
4862 union wait status;
4863#define status_i (status.w_status)
4864#else
4865 int status;
4866#define status_i status
4867#endif
4868 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004869
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004870 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004871 {
4872 return NULL;
4873 }
Tim Peters5aa91602002-01-30 05:46:57 +00004874
Guido van Rossumc9641791998-08-04 15:26:23 +00004875 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004876#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004877}
4878#endif /* WEXITSTATUS */
4879
4880#ifdef WTERMSIG
4881static char posix_WTERMSIG__doc__[] =
4882"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004883Return the signal that terminated the process that provided the 'status'\n\
4884value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004885
4886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004887posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004888{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004889#ifdef UNION_WAIT
4890 union wait status;
4891#define status_i (status.w_status)
4892#else
4893 int status;
4894#define status_i status
4895#endif
4896 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004897
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004898 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004899 {
4900 return NULL;
4901 }
Tim Peters5aa91602002-01-30 05:46:57 +00004902
Guido van Rossumc9641791998-08-04 15:26:23 +00004903 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004904#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004905}
4906#endif /* WTERMSIG */
4907
4908#ifdef WSTOPSIG
4909static char posix_WSTOPSIG__doc__[] =
4910"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004911Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004912
4913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004914posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004915{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004916#ifdef UNION_WAIT
4917 union wait status;
4918#define status_i (status.w_status)
4919#else
4920 int status;
4921#define status_i status
4922#endif
4923 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004924
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004925 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004926 {
4927 return NULL;
4928 }
Tim Peters5aa91602002-01-30 05:46:57 +00004929
Guido van Rossumc9641791998-08-04 15:26:23 +00004930 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004931#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004932}
4933#endif /* WSTOPSIG */
4934
4935#endif /* HAVE_SYS_WAIT_H */
4936
4937
Guido van Rossum94f6f721999-01-06 18:42:14 +00004938#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004939#ifdef _SCO_DS
4940/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4941 needed definitions in sys/statvfs.h */
4942#define _SVID3
4943#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004944#include <sys/statvfs.h>
4945
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004946static PyObject*
4947_pystatvfs_fromstructstatvfs(struct statvfs st) {
4948 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4949 if (v == NULL)
4950 return NULL;
4951
4952#if !defined(HAVE_LARGEFILE_SUPPORT)
4953 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4954 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4955 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4956 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4957 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4958 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4959 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4960 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4961 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4962 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4963#else
4964 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4965 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00004966 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004967 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00004968 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004969 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4970 PyStructSequence_SET_ITEM(v, 4,
4971 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00004972 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004973 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00004974 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004975 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00004976 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004977 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4978 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4979 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4980#endif
4981
4982 return v;
4983}
4984
Guido van Rossum94f6f721999-01-06 18:42:14 +00004985static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004986"fstatvfs(fd) -> \n\
4987 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004988Perform an fstatvfs system call on the given fd.";
4989
4990static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004991posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004992{
4993 int fd, res;
4994 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004995
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004996 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004997 return NULL;
4998 Py_BEGIN_ALLOW_THREADS
4999 res = fstatvfs(fd, &st);
5000 Py_END_ALLOW_THREADS
5001 if (res != 0)
5002 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005003
5004 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005005}
5006#endif /* HAVE_FSTATVFS */
5007
5008
5009#if defined(HAVE_STATVFS)
5010#include <sys/statvfs.h>
5011
5012static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005013"statvfs(path) -> \n\
5014 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005015Perform a statvfs system call on the given path.";
5016
5017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005018posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005019{
5020 char *path;
5021 int res;
5022 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005023 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005024 return NULL;
5025 Py_BEGIN_ALLOW_THREADS
5026 res = statvfs(path, &st);
5027 Py_END_ALLOW_THREADS
5028 if (res != 0)
5029 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005030
5031 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005032}
5033#endif /* HAVE_STATVFS */
5034
5035
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005036#ifdef HAVE_TEMPNAM
5037static char posix_tempnam__doc__[] = "\
5038tempnam([dir[, prefix]]) -> string\n\
5039Return a unique name for a temporary file.\n\
5040The directory and a short may be specified as strings; they may be omitted\n\
5041or None if not needed.";
5042
5043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005044posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005045{
5046 PyObject *result = NULL;
5047 char *dir = NULL;
5048 char *pfx = NULL;
5049 char *name;
5050
5051 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5052 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005053
5054 if (PyErr_Warn(PyExc_RuntimeWarning,
5055 "tempnam is a potential security risk to your program") < 0)
5056 return NULL;
5057
Fred Drake78b71c22001-07-17 20:37:36 +00005058#ifdef MS_WIN32
5059 name = _tempnam(dir, pfx);
5060#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005061 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005062#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005063 if (name == NULL)
5064 return PyErr_NoMemory();
5065 result = PyString_FromString(name);
5066 free(name);
5067 return result;
5068}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005069#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005070
5071
5072#ifdef HAVE_TMPFILE
5073static char posix_tmpfile__doc__[] = "\
5074tmpfile() -> file object\n\
5075Create a temporary file with no directory entries.";
5076
5077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005078posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005079{
5080 FILE *fp;
5081
5082 if (!PyArg_ParseTuple(args, ":tmpfile"))
5083 return NULL;
5084 fp = tmpfile();
5085 if (fp == NULL)
5086 return posix_error();
5087 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
5088}
5089#endif
5090
5091
5092#ifdef HAVE_TMPNAM
5093static char posix_tmpnam__doc__[] = "\
5094tmpnam() -> string\n\
5095Return a unique name for a temporary file.";
5096
5097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005098posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005099{
5100 char buffer[L_tmpnam];
5101 char *name;
5102
5103 if (!PyArg_ParseTuple(args, ":tmpnam"))
5104 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005105
5106 if (PyErr_Warn(PyExc_RuntimeWarning,
5107 "tmpnam is a potential security risk to your program") < 0)
5108 return NULL;
5109
Greg Wardb48bc172000-03-01 21:51:56 +00005110#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005111 name = tmpnam_r(buffer);
5112#else
5113 name = tmpnam(buffer);
5114#endif
5115 if (name == NULL) {
5116 PyErr_SetObject(PyExc_OSError,
5117 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005118#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005119 "unexpected NULL from tmpnam_r"
5120#else
5121 "unexpected NULL from tmpnam"
5122#endif
5123 ));
5124 return NULL;
5125 }
5126 return PyString_FromString(buffer);
5127}
5128#endif
5129
5130
Fred Drakec9680921999-12-13 16:37:25 +00005131/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5132 * It maps strings representing configuration variable names to
5133 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005134 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005135 * rarely-used constants. There are three separate tables that use
5136 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005137 *
5138 * This code is always included, even if none of the interfaces that
5139 * need it are included. The #if hackery needed to avoid it would be
5140 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005141 */
5142struct constdef {
5143 char *name;
5144 long value;
5145};
5146
Fred Drake12c6e2d1999-12-14 21:25:03 +00005147static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005148conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5149 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005150{
5151 if (PyInt_Check(arg)) {
5152 *valuep = PyInt_AS_LONG(arg);
5153 return 1;
5154 }
5155 if (PyString_Check(arg)) {
5156 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005157 size_t lo = 0;
5158 size_t mid;
5159 size_t hi = tablesize;
5160 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005161 char *confname = PyString_AS_STRING(arg);
5162 while (lo < hi) {
5163 mid = (lo + hi) / 2;
5164 cmp = strcmp(confname, table[mid].name);
5165 if (cmp < 0)
5166 hi = mid;
5167 else if (cmp > 0)
5168 lo = mid + 1;
5169 else {
5170 *valuep = table[mid].value;
5171 return 1;
5172 }
5173 }
5174 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5175 }
5176 else
5177 PyErr_SetString(PyExc_TypeError,
5178 "configuration names must be strings or integers");
5179 return 0;
5180}
5181
5182
5183#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5184static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005185#ifdef _PC_ABI_AIO_XFER_MAX
5186 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5187#endif
5188#ifdef _PC_ABI_ASYNC_IO
5189 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5190#endif
Fred Drakec9680921999-12-13 16:37:25 +00005191#ifdef _PC_ASYNC_IO
5192 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5193#endif
5194#ifdef _PC_CHOWN_RESTRICTED
5195 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5196#endif
5197#ifdef _PC_FILESIZEBITS
5198 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5199#endif
5200#ifdef _PC_LAST
5201 {"PC_LAST", _PC_LAST},
5202#endif
5203#ifdef _PC_LINK_MAX
5204 {"PC_LINK_MAX", _PC_LINK_MAX},
5205#endif
5206#ifdef _PC_MAX_CANON
5207 {"PC_MAX_CANON", _PC_MAX_CANON},
5208#endif
5209#ifdef _PC_MAX_INPUT
5210 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5211#endif
5212#ifdef _PC_NAME_MAX
5213 {"PC_NAME_MAX", _PC_NAME_MAX},
5214#endif
5215#ifdef _PC_NO_TRUNC
5216 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5217#endif
5218#ifdef _PC_PATH_MAX
5219 {"PC_PATH_MAX", _PC_PATH_MAX},
5220#endif
5221#ifdef _PC_PIPE_BUF
5222 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5223#endif
5224#ifdef _PC_PRIO_IO
5225 {"PC_PRIO_IO", _PC_PRIO_IO},
5226#endif
5227#ifdef _PC_SOCK_MAXBUF
5228 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5229#endif
5230#ifdef _PC_SYNC_IO
5231 {"PC_SYNC_IO", _PC_SYNC_IO},
5232#endif
5233#ifdef _PC_VDISABLE
5234 {"PC_VDISABLE", _PC_VDISABLE},
5235#endif
5236};
5237
Fred Drakec9680921999-12-13 16:37:25 +00005238static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005239conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005240{
5241 return conv_confname(arg, valuep, posix_constants_pathconf,
5242 sizeof(posix_constants_pathconf)
5243 / sizeof(struct constdef));
5244}
5245#endif
5246
5247#ifdef HAVE_FPATHCONF
5248static char posix_fpathconf__doc__[] = "\
5249fpathconf(fd, name) -> integer\n\
5250Return the configuration limit name for the file descriptor fd.\n\
5251If there is no limit, return -1.";
5252
5253static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005254posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005255{
5256 PyObject *result = NULL;
5257 int name, fd;
5258
Fred Drake12c6e2d1999-12-14 21:25:03 +00005259 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5260 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005261 long limit;
5262
5263 errno = 0;
5264 limit = fpathconf(fd, name);
5265 if (limit == -1 && errno != 0)
5266 posix_error();
5267 else
5268 result = PyInt_FromLong(limit);
5269 }
5270 return result;
5271}
5272#endif
5273
5274
5275#ifdef HAVE_PATHCONF
5276static char posix_pathconf__doc__[] = "\
5277pathconf(path, name) -> integer\n\
5278Return the configuration limit name for the file or directory path.\n\
5279If there is no limit, return -1.";
5280
5281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005282posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005283{
5284 PyObject *result = NULL;
5285 int name;
5286 char *path;
5287
5288 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5289 conv_path_confname, &name)) {
5290 long limit;
5291
5292 errno = 0;
5293 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005294 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005295 if (errno == EINVAL)
5296 /* could be a path or name problem */
5297 posix_error();
5298 else
5299 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005300 }
Fred Drakec9680921999-12-13 16:37:25 +00005301 else
5302 result = PyInt_FromLong(limit);
5303 }
5304 return result;
5305}
5306#endif
5307
5308#ifdef HAVE_CONFSTR
5309static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005310#ifdef _CS_ARCHITECTURE
5311 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5312#endif
5313#ifdef _CS_HOSTNAME
5314 {"CS_HOSTNAME", _CS_HOSTNAME},
5315#endif
5316#ifdef _CS_HW_PROVIDER
5317 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5318#endif
5319#ifdef _CS_HW_SERIAL
5320 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5321#endif
5322#ifdef _CS_INITTAB_NAME
5323 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5324#endif
Fred Drakec9680921999-12-13 16:37:25 +00005325#ifdef _CS_LFS64_CFLAGS
5326 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5327#endif
5328#ifdef _CS_LFS64_LDFLAGS
5329 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5330#endif
5331#ifdef _CS_LFS64_LIBS
5332 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5333#endif
5334#ifdef _CS_LFS64_LINTFLAGS
5335 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5336#endif
5337#ifdef _CS_LFS_CFLAGS
5338 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5339#endif
5340#ifdef _CS_LFS_LDFLAGS
5341 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5342#endif
5343#ifdef _CS_LFS_LIBS
5344 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5345#endif
5346#ifdef _CS_LFS_LINTFLAGS
5347 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5348#endif
Fred Draked86ed291999-12-15 15:34:33 +00005349#ifdef _CS_MACHINE
5350 {"CS_MACHINE", _CS_MACHINE},
5351#endif
Fred Drakec9680921999-12-13 16:37:25 +00005352#ifdef _CS_PATH
5353 {"CS_PATH", _CS_PATH},
5354#endif
Fred Draked86ed291999-12-15 15:34:33 +00005355#ifdef _CS_RELEASE
5356 {"CS_RELEASE", _CS_RELEASE},
5357#endif
5358#ifdef _CS_SRPC_DOMAIN
5359 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5360#endif
5361#ifdef _CS_SYSNAME
5362 {"CS_SYSNAME", _CS_SYSNAME},
5363#endif
5364#ifdef _CS_VERSION
5365 {"CS_VERSION", _CS_VERSION},
5366#endif
Fred Drakec9680921999-12-13 16:37:25 +00005367#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5368 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5369#endif
5370#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5371 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5372#endif
5373#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5374 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5375#endif
5376#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5377 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5378#endif
5379#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5380 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5381#endif
5382#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5383 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5384#endif
5385#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5386 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5387#endif
5388#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5389 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5390#endif
5391#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5392 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5393#endif
5394#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5395 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5396#endif
5397#ifdef _CS_XBS5_LP64_OFF64_LIBS
5398 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5399#endif
5400#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5401 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5402#endif
5403#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5404 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5405#endif
5406#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5407 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5408#endif
5409#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5410 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5411#endif
5412#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5413 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5414#endif
Fred Draked86ed291999-12-15 15:34:33 +00005415#ifdef _MIPS_CS_AVAIL_PROCESSORS
5416 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5417#endif
5418#ifdef _MIPS_CS_BASE
5419 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5420#endif
5421#ifdef _MIPS_CS_HOSTID
5422 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5423#endif
5424#ifdef _MIPS_CS_HW_NAME
5425 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5426#endif
5427#ifdef _MIPS_CS_NUM_PROCESSORS
5428 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5429#endif
5430#ifdef _MIPS_CS_OSREL_MAJ
5431 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5432#endif
5433#ifdef _MIPS_CS_OSREL_MIN
5434 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5435#endif
5436#ifdef _MIPS_CS_OSREL_PATCH
5437 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5438#endif
5439#ifdef _MIPS_CS_OS_NAME
5440 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5441#endif
5442#ifdef _MIPS_CS_OS_PROVIDER
5443 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5444#endif
5445#ifdef _MIPS_CS_PROCESSORS
5446 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5447#endif
5448#ifdef _MIPS_CS_SERIAL
5449 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5450#endif
5451#ifdef _MIPS_CS_VENDOR
5452 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5453#endif
Fred Drakec9680921999-12-13 16:37:25 +00005454};
5455
5456static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005457conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005458{
5459 return conv_confname(arg, valuep, posix_constants_confstr,
5460 sizeof(posix_constants_confstr)
5461 / sizeof(struct constdef));
5462}
5463
5464static char posix_confstr__doc__[] = "\
5465confstr(name) -> string\n\
5466Return a string-valued system configuration variable.";
5467
5468static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005469posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005470{
5471 PyObject *result = NULL;
5472 int name;
5473 char buffer[64];
5474
5475 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5476 int len = confstr(name, buffer, sizeof(buffer));
5477
Fred Drakec9680921999-12-13 16:37:25 +00005478 errno = 0;
5479 if (len == 0) {
5480 if (errno != 0)
5481 posix_error();
5482 else
5483 result = PyString_FromString("");
5484 }
5485 else {
5486 if (len >= sizeof(buffer)) {
5487 result = PyString_FromStringAndSize(NULL, len);
5488 if (result != NULL)
5489 confstr(name, PyString_AS_STRING(result), len+1);
5490 }
5491 else
5492 result = PyString_FromString(buffer);
5493 }
5494 }
5495 return result;
5496}
5497#endif
5498
5499
5500#ifdef HAVE_SYSCONF
5501static struct constdef posix_constants_sysconf[] = {
5502#ifdef _SC_2_CHAR_TERM
5503 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5504#endif
5505#ifdef _SC_2_C_BIND
5506 {"SC_2_C_BIND", _SC_2_C_BIND},
5507#endif
5508#ifdef _SC_2_C_DEV
5509 {"SC_2_C_DEV", _SC_2_C_DEV},
5510#endif
5511#ifdef _SC_2_C_VERSION
5512 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5513#endif
5514#ifdef _SC_2_FORT_DEV
5515 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5516#endif
5517#ifdef _SC_2_FORT_RUN
5518 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5519#endif
5520#ifdef _SC_2_LOCALEDEF
5521 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5522#endif
5523#ifdef _SC_2_SW_DEV
5524 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5525#endif
5526#ifdef _SC_2_UPE
5527 {"SC_2_UPE", _SC_2_UPE},
5528#endif
5529#ifdef _SC_2_VERSION
5530 {"SC_2_VERSION", _SC_2_VERSION},
5531#endif
Fred Draked86ed291999-12-15 15:34:33 +00005532#ifdef _SC_ABI_ASYNCHRONOUS_IO
5533 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5534#endif
5535#ifdef _SC_ACL
5536 {"SC_ACL", _SC_ACL},
5537#endif
Fred Drakec9680921999-12-13 16:37:25 +00005538#ifdef _SC_AIO_LISTIO_MAX
5539 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5540#endif
Fred Drakec9680921999-12-13 16:37:25 +00005541#ifdef _SC_AIO_MAX
5542 {"SC_AIO_MAX", _SC_AIO_MAX},
5543#endif
5544#ifdef _SC_AIO_PRIO_DELTA_MAX
5545 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5546#endif
5547#ifdef _SC_ARG_MAX
5548 {"SC_ARG_MAX", _SC_ARG_MAX},
5549#endif
5550#ifdef _SC_ASYNCHRONOUS_IO
5551 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5552#endif
5553#ifdef _SC_ATEXIT_MAX
5554 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5555#endif
Fred Draked86ed291999-12-15 15:34:33 +00005556#ifdef _SC_AUDIT
5557 {"SC_AUDIT", _SC_AUDIT},
5558#endif
Fred Drakec9680921999-12-13 16:37:25 +00005559#ifdef _SC_AVPHYS_PAGES
5560 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5561#endif
5562#ifdef _SC_BC_BASE_MAX
5563 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5564#endif
5565#ifdef _SC_BC_DIM_MAX
5566 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5567#endif
5568#ifdef _SC_BC_SCALE_MAX
5569 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5570#endif
5571#ifdef _SC_BC_STRING_MAX
5572 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5573#endif
Fred Draked86ed291999-12-15 15:34:33 +00005574#ifdef _SC_CAP
5575 {"SC_CAP", _SC_CAP},
5576#endif
Fred Drakec9680921999-12-13 16:37:25 +00005577#ifdef _SC_CHARCLASS_NAME_MAX
5578 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5579#endif
5580#ifdef _SC_CHAR_BIT
5581 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5582#endif
5583#ifdef _SC_CHAR_MAX
5584 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5585#endif
5586#ifdef _SC_CHAR_MIN
5587 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5588#endif
5589#ifdef _SC_CHILD_MAX
5590 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5591#endif
5592#ifdef _SC_CLK_TCK
5593 {"SC_CLK_TCK", _SC_CLK_TCK},
5594#endif
5595#ifdef _SC_COHER_BLKSZ
5596 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5597#endif
5598#ifdef _SC_COLL_WEIGHTS_MAX
5599 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5600#endif
5601#ifdef _SC_DCACHE_ASSOC
5602 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5603#endif
5604#ifdef _SC_DCACHE_BLKSZ
5605 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5606#endif
5607#ifdef _SC_DCACHE_LINESZ
5608 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5609#endif
5610#ifdef _SC_DCACHE_SZ
5611 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5612#endif
5613#ifdef _SC_DCACHE_TBLKSZ
5614 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5615#endif
5616#ifdef _SC_DELAYTIMER_MAX
5617 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5618#endif
5619#ifdef _SC_EQUIV_CLASS_MAX
5620 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5621#endif
5622#ifdef _SC_EXPR_NEST_MAX
5623 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5624#endif
5625#ifdef _SC_FSYNC
5626 {"SC_FSYNC", _SC_FSYNC},
5627#endif
5628#ifdef _SC_GETGR_R_SIZE_MAX
5629 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5630#endif
5631#ifdef _SC_GETPW_R_SIZE_MAX
5632 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5633#endif
5634#ifdef _SC_ICACHE_ASSOC
5635 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5636#endif
5637#ifdef _SC_ICACHE_BLKSZ
5638 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5639#endif
5640#ifdef _SC_ICACHE_LINESZ
5641 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5642#endif
5643#ifdef _SC_ICACHE_SZ
5644 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5645#endif
Fred Draked86ed291999-12-15 15:34:33 +00005646#ifdef _SC_INF
5647 {"SC_INF", _SC_INF},
5648#endif
Fred Drakec9680921999-12-13 16:37:25 +00005649#ifdef _SC_INT_MAX
5650 {"SC_INT_MAX", _SC_INT_MAX},
5651#endif
5652#ifdef _SC_INT_MIN
5653 {"SC_INT_MIN", _SC_INT_MIN},
5654#endif
5655#ifdef _SC_IOV_MAX
5656 {"SC_IOV_MAX", _SC_IOV_MAX},
5657#endif
Fred Draked86ed291999-12-15 15:34:33 +00005658#ifdef _SC_IP_SECOPTS
5659 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5660#endif
Fred Drakec9680921999-12-13 16:37:25 +00005661#ifdef _SC_JOB_CONTROL
5662 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5663#endif
Fred Draked86ed291999-12-15 15:34:33 +00005664#ifdef _SC_KERN_POINTERS
5665 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5666#endif
5667#ifdef _SC_KERN_SIM
5668 {"SC_KERN_SIM", _SC_KERN_SIM},
5669#endif
Fred Drakec9680921999-12-13 16:37:25 +00005670#ifdef _SC_LINE_MAX
5671 {"SC_LINE_MAX", _SC_LINE_MAX},
5672#endif
5673#ifdef _SC_LOGIN_NAME_MAX
5674 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5675#endif
5676#ifdef _SC_LOGNAME_MAX
5677 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5678#endif
5679#ifdef _SC_LONG_BIT
5680 {"SC_LONG_BIT", _SC_LONG_BIT},
5681#endif
Fred Draked86ed291999-12-15 15:34:33 +00005682#ifdef _SC_MAC
5683 {"SC_MAC", _SC_MAC},
5684#endif
Fred Drakec9680921999-12-13 16:37:25 +00005685#ifdef _SC_MAPPED_FILES
5686 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5687#endif
5688#ifdef _SC_MAXPID
5689 {"SC_MAXPID", _SC_MAXPID},
5690#endif
5691#ifdef _SC_MB_LEN_MAX
5692 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5693#endif
5694#ifdef _SC_MEMLOCK
5695 {"SC_MEMLOCK", _SC_MEMLOCK},
5696#endif
5697#ifdef _SC_MEMLOCK_RANGE
5698 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5699#endif
5700#ifdef _SC_MEMORY_PROTECTION
5701 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5702#endif
5703#ifdef _SC_MESSAGE_PASSING
5704 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5705#endif
Fred Draked86ed291999-12-15 15:34:33 +00005706#ifdef _SC_MMAP_FIXED_ALIGNMENT
5707 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5708#endif
Fred Drakec9680921999-12-13 16:37:25 +00005709#ifdef _SC_MQ_OPEN_MAX
5710 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5711#endif
5712#ifdef _SC_MQ_PRIO_MAX
5713 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5714#endif
Fred Draked86ed291999-12-15 15:34:33 +00005715#ifdef _SC_NACLS_MAX
5716 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5717#endif
Fred Drakec9680921999-12-13 16:37:25 +00005718#ifdef _SC_NGROUPS_MAX
5719 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5720#endif
5721#ifdef _SC_NL_ARGMAX
5722 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5723#endif
5724#ifdef _SC_NL_LANGMAX
5725 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5726#endif
5727#ifdef _SC_NL_MSGMAX
5728 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5729#endif
5730#ifdef _SC_NL_NMAX
5731 {"SC_NL_NMAX", _SC_NL_NMAX},
5732#endif
5733#ifdef _SC_NL_SETMAX
5734 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5735#endif
5736#ifdef _SC_NL_TEXTMAX
5737 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5738#endif
5739#ifdef _SC_NPROCESSORS_CONF
5740 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5741#endif
5742#ifdef _SC_NPROCESSORS_ONLN
5743 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5744#endif
Fred Draked86ed291999-12-15 15:34:33 +00005745#ifdef _SC_NPROC_CONF
5746 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5747#endif
5748#ifdef _SC_NPROC_ONLN
5749 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5750#endif
Fred Drakec9680921999-12-13 16:37:25 +00005751#ifdef _SC_NZERO
5752 {"SC_NZERO", _SC_NZERO},
5753#endif
5754#ifdef _SC_OPEN_MAX
5755 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5756#endif
5757#ifdef _SC_PAGESIZE
5758 {"SC_PAGESIZE", _SC_PAGESIZE},
5759#endif
5760#ifdef _SC_PAGE_SIZE
5761 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5762#endif
5763#ifdef _SC_PASS_MAX
5764 {"SC_PASS_MAX", _SC_PASS_MAX},
5765#endif
5766#ifdef _SC_PHYS_PAGES
5767 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5768#endif
5769#ifdef _SC_PII
5770 {"SC_PII", _SC_PII},
5771#endif
5772#ifdef _SC_PII_INTERNET
5773 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5774#endif
5775#ifdef _SC_PII_INTERNET_DGRAM
5776 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5777#endif
5778#ifdef _SC_PII_INTERNET_STREAM
5779 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5780#endif
5781#ifdef _SC_PII_OSI
5782 {"SC_PII_OSI", _SC_PII_OSI},
5783#endif
5784#ifdef _SC_PII_OSI_CLTS
5785 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5786#endif
5787#ifdef _SC_PII_OSI_COTS
5788 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5789#endif
5790#ifdef _SC_PII_OSI_M
5791 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5792#endif
5793#ifdef _SC_PII_SOCKET
5794 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5795#endif
5796#ifdef _SC_PII_XTI
5797 {"SC_PII_XTI", _SC_PII_XTI},
5798#endif
5799#ifdef _SC_POLL
5800 {"SC_POLL", _SC_POLL},
5801#endif
5802#ifdef _SC_PRIORITIZED_IO
5803 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5804#endif
5805#ifdef _SC_PRIORITY_SCHEDULING
5806 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5807#endif
5808#ifdef _SC_REALTIME_SIGNALS
5809 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5810#endif
5811#ifdef _SC_RE_DUP_MAX
5812 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5813#endif
5814#ifdef _SC_RTSIG_MAX
5815 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5816#endif
5817#ifdef _SC_SAVED_IDS
5818 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5819#endif
5820#ifdef _SC_SCHAR_MAX
5821 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5822#endif
5823#ifdef _SC_SCHAR_MIN
5824 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5825#endif
5826#ifdef _SC_SELECT
5827 {"SC_SELECT", _SC_SELECT},
5828#endif
5829#ifdef _SC_SEMAPHORES
5830 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5831#endif
5832#ifdef _SC_SEM_NSEMS_MAX
5833 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5834#endif
5835#ifdef _SC_SEM_VALUE_MAX
5836 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5837#endif
5838#ifdef _SC_SHARED_MEMORY_OBJECTS
5839 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5840#endif
5841#ifdef _SC_SHRT_MAX
5842 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5843#endif
5844#ifdef _SC_SHRT_MIN
5845 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5846#endif
5847#ifdef _SC_SIGQUEUE_MAX
5848 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5849#endif
5850#ifdef _SC_SIGRT_MAX
5851 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5852#endif
5853#ifdef _SC_SIGRT_MIN
5854 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5855#endif
Fred Draked86ed291999-12-15 15:34:33 +00005856#ifdef _SC_SOFTPOWER
5857 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5858#endif
Fred Drakec9680921999-12-13 16:37:25 +00005859#ifdef _SC_SPLIT_CACHE
5860 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5861#endif
5862#ifdef _SC_SSIZE_MAX
5863 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5864#endif
5865#ifdef _SC_STACK_PROT
5866 {"SC_STACK_PROT", _SC_STACK_PROT},
5867#endif
5868#ifdef _SC_STREAM_MAX
5869 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5870#endif
5871#ifdef _SC_SYNCHRONIZED_IO
5872 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5873#endif
5874#ifdef _SC_THREADS
5875 {"SC_THREADS", _SC_THREADS},
5876#endif
5877#ifdef _SC_THREAD_ATTR_STACKADDR
5878 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5879#endif
5880#ifdef _SC_THREAD_ATTR_STACKSIZE
5881 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5882#endif
5883#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5884 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5885#endif
5886#ifdef _SC_THREAD_KEYS_MAX
5887 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5888#endif
5889#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5890 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5891#endif
5892#ifdef _SC_THREAD_PRIO_INHERIT
5893 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5894#endif
5895#ifdef _SC_THREAD_PRIO_PROTECT
5896 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5897#endif
5898#ifdef _SC_THREAD_PROCESS_SHARED
5899 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5900#endif
5901#ifdef _SC_THREAD_SAFE_FUNCTIONS
5902 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5903#endif
5904#ifdef _SC_THREAD_STACK_MIN
5905 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5906#endif
5907#ifdef _SC_THREAD_THREADS_MAX
5908 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5909#endif
5910#ifdef _SC_TIMERS
5911 {"SC_TIMERS", _SC_TIMERS},
5912#endif
5913#ifdef _SC_TIMER_MAX
5914 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5915#endif
5916#ifdef _SC_TTY_NAME_MAX
5917 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5918#endif
5919#ifdef _SC_TZNAME_MAX
5920 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5921#endif
5922#ifdef _SC_T_IOV_MAX
5923 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5924#endif
5925#ifdef _SC_UCHAR_MAX
5926 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5927#endif
5928#ifdef _SC_UINT_MAX
5929 {"SC_UINT_MAX", _SC_UINT_MAX},
5930#endif
5931#ifdef _SC_UIO_MAXIOV
5932 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5933#endif
5934#ifdef _SC_ULONG_MAX
5935 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5936#endif
5937#ifdef _SC_USHRT_MAX
5938 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5939#endif
5940#ifdef _SC_VERSION
5941 {"SC_VERSION", _SC_VERSION},
5942#endif
5943#ifdef _SC_WORD_BIT
5944 {"SC_WORD_BIT", _SC_WORD_BIT},
5945#endif
5946#ifdef _SC_XBS5_ILP32_OFF32
5947 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5948#endif
5949#ifdef _SC_XBS5_ILP32_OFFBIG
5950 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5951#endif
5952#ifdef _SC_XBS5_LP64_OFF64
5953 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5954#endif
5955#ifdef _SC_XBS5_LPBIG_OFFBIG
5956 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5957#endif
5958#ifdef _SC_XOPEN_CRYPT
5959 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5960#endif
5961#ifdef _SC_XOPEN_ENH_I18N
5962 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5963#endif
5964#ifdef _SC_XOPEN_LEGACY
5965 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5966#endif
5967#ifdef _SC_XOPEN_REALTIME
5968 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5969#endif
5970#ifdef _SC_XOPEN_REALTIME_THREADS
5971 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5972#endif
5973#ifdef _SC_XOPEN_SHM
5974 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5975#endif
5976#ifdef _SC_XOPEN_UNIX
5977 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5978#endif
5979#ifdef _SC_XOPEN_VERSION
5980 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5981#endif
5982#ifdef _SC_XOPEN_XCU_VERSION
5983 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5984#endif
5985#ifdef _SC_XOPEN_XPG2
5986 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5987#endif
5988#ifdef _SC_XOPEN_XPG3
5989 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5990#endif
5991#ifdef _SC_XOPEN_XPG4
5992 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5993#endif
5994};
5995
5996static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005997conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005998{
5999 return conv_confname(arg, valuep, posix_constants_sysconf,
6000 sizeof(posix_constants_sysconf)
6001 / sizeof(struct constdef));
6002}
6003
6004static char posix_sysconf__doc__[] = "\
6005sysconf(name) -> integer\n\
6006Return an integer-valued system configuration variable.";
6007
6008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006009posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006010{
6011 PyObject *result = NULL;
6012 int name;
6013
6014 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6015 int value;
6016
6017 errno = 0;
6018 value = sysconf(name);
6019 if (value == -1 && errno != 0)
6020 posix_error();
6021 else
6022 result = PyInt_FromLong(value);
6023 }
6024 return result;
6025}
6026#endif
6027
6028
Fred Drakebec628d1999-12-15 18:31:10 +00006029/* This code is used to ensure that the tables of configuration value names
6030 * are in sorted order as required by conv_confname(), and also to build the
6031 * the exported dictionaries that are used to publish information about the
6032 * names available on the host platform.
6033 *
6034 * Sorting the table at runtime ensures that the table is properly ordered
6035 * when used, even for platforms we're not able to test on. It also makes
6036 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006037 */
Fred Drakebec628d1999-12-15 18:31:10 +00006038
6039static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006040cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006041{
6042 const struct constdef *c1 =
6043 (const struct constdef *) v1;
6044 const struct constdef *c2 =
6045 (const struct constdef *) v2;
6046
6047 return strcmp(c1->name, c2->name);
6048}
6049
6050static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006051setup_confname_table(struct constdef *table, size_t tablesize,
6052 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00006053{
Fred Drakebec628d1999-12-15 18:31:10 +00006054 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006055 size_t i;
6056 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00006057
6058 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6059 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006060 if (d == NULL)
6061 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006062
Barry Warsaw3155db32000-04-13 15:20:40 +00006063 for (i=0; i < tablesize; ++i) {
6064 PyObject *o = PyInt_FromLong(table[i].value);
6065 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6066 Py_XDECREF(o);
6067 Py_DECREF(d);
6068 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006069 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006070 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006071 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006072 status = PyDict_SetItemString(moddict, tablename, d);
6073 Py_DECREF(d);
6074 return status;
Fred Draked86ed291999-12-15 15:34:33 +00006075}
6076
Fred Drakebec628d1999-12-15 18:31:10 +00006077/* Return -1 on failure, 0 on success. */
6078static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006079setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00006080{
6081#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006082 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006083 sizeof(posix_constants_pathconf)
6084 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006085 "pathconf_names", moddict))
6086 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006087#endif
6088#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006089 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006090 sizeof(posix_constants_confstr)
6091 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006092 "confstr_names", moddict))
6093 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006094#endif
6095#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006096 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006097 sizeof(posix_constants_sysconf)
6098 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006099 "sysconf_names", moddict))
6100 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006101#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006102 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006103}
Fred Draked86ed291999-12-15 15:34:33 +00006104
6105
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006106static char posix_abort__doc__[] = "\
6107abort() -> does not return!\n\
6108Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
6109in the hardest way possible on the hosting operating system.";
6110
6111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006112posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006113{
6114 if (!PyArg_ParseTuple(args, ":abort"))
6115 return NULL;
6116 abort();
6117 /*NOTREACHED*/
6118 Py_FatalError("abort() called from Python code didn't abort!");
6119 return NULL;
6120}
Fred Drakebec628d1999-12-15 18:31:10 +00006121
Tim Petersf58a7aa2000-09-22 10:05:54 +00006122#ifdef MS_WIN32
6123static char win32_startfile__doc__[] = "\
6124startfile(filepath) - Start a file with its associated application.\n\
6125\n\
6126This acts like double-clicking the file in Explorer, or giving the file\n\
6127name as an argument to the DOS \"start\" command: the file is opened\n\
6128with whatever application (if any) its extension is associated.\n\
6129\n\
6130startfile returns as soon as the associated application is launched.\n\
6131There is no option to wait for the application to close, and no way\n\
6132to retrieve the application's exit status.\n\
6133\n\
6134The filepath is relative to the current directory. If you want to use\n\
6135an absolute path, make sure the first character is not a slash (\"/\");\n\
6136the underlying Win32 ShellExecute function doesn't work if it is.";
6137
6138static PyObject *
6139win32_startfile(PyObject *self, PyObject *args)
6140{
6141 char *filepath;
6142 HINSTANCE rc;
6143 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6144 return NULL;
6145 Py_BEGIN_ALLOW_THREADS
6146 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6147 Py_END_ALLOW_THREADS
6148 if (rc <= (HINSTANCE)32)
6149 return win32_error("startfile", filepath);
6150 Py_INCREF(Py_None);
6151 return Py_None;
6152}
6153#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006154
6155static PyMethodDef posix_methods[] = {
6156 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6157#ifdef HAVE_TTYNAME
6158 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6159#endif
6160 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6161 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006162#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006163 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006164#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006165#ifdef HAVE_CHROOT
6166 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6167#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006168#ifdef HAVE_CTERMID
6169 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6170#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006171#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006172 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006173#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006174#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006175 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006176#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006177 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6178 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6179 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006180#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006181 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006182#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006183#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006184 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006185#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006186 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6187 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6188 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006189#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006190 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006191#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006192#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006193 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006194#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006195 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006196#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006197 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006198#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006199 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6200 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6201 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006202#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006203 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006204#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006205 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006206#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006207 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6208 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006209#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006210#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006211 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6212 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006213#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006214#ifdef HAVE_FORK1
6215 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6216#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006217#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006218 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006219#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006220#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006221 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006222#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006223#ifdef HAVE_FORKPTY
6224 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6225#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006226#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006227 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006228#endif /* HAVE_GETEGID */
6229#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006230 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006231#endif /* HAVE_GETEUID */
6232#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006233 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006234#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006235#ifdef HAVE_GETGROUPS
6236 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6237#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006238 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006239#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006240 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006241#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006242#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006243 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006244#endif /* HAVE_GETPPID */
6245#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006246 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006247#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006248#ifdef HAVE_GETLOGIN
6249 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6250#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006251#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006252 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006253#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006254#ifdef HAVE_KILLPG
6255 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6256#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006257#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006258 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006259#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006260#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006261 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006262#ifdef MS_WIN32
6263 {"popen2", win32_popen2, METH_VARARGS},
6264 {"popen3", win32_popen3, METH_VARARGS},
6265 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006266 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006267#else
6268#if defined(PYOS_OS2) && defined(PYCC_GCC)
6269 {"popen2", os2emx_popen2, METH_VARARGS},
6270 {"popen3", os2emx_popen3, METH_VARARGS},
6271 {"popen4", os2emx_popen4, METH_VARARGS},
6272#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006273#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006274#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006275#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006276 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006277#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006278#ifdef HAVE_SETEUID
6279 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6280#endif /* HAVE_SETEUID */
6281#ifdef HAVE_SETEGID
6282 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6283#endif /* HAVE_SETEGID */
6284#ifdef HAVE_SETREUID
6285 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6286#endif /* HAVE_SETREUID */
6287#ifdef HAVE_SETREGID
6288 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6289#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006290#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006291 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006292#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006293#ifdef HAVE_SETGROUPS
6294 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6295#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006296#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006297 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006298#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006299#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006300 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006301#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006302#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006303 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006304#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006305#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006306 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006307#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006308#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006309 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006310#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006311#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006312 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006313#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006314#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006315 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006316#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006317 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6318 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6319 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6320 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6321 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6322 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6323 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6324 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6325 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006326 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006327#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006328 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006329#endif
6330#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006331 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006332#endif
6333#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006334 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006335#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006336#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006337 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006338#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006339#ifdef HAVE_UNSETENV
6340 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6341#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006342#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006343 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006344#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006345#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006346 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006347#endif
6348#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006349 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006350#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006351#ifdef HAVE_SYS_WAIT_H
6352#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006353 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006354#endif /* WIFSTOPPED */
6355#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006356 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006357#endif /* WIFSIGNALED */
6358#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006359 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006360#endif /* WIFEXITED */
6361#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006362 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006363#endif /* WEXITSTATUS */
6364#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006366#endif /* WTERMSIG */
6367#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006368 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006369#endif /* WSTOPSIG */
6370#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006371#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006372 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006373#endif
6374#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006375 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006376#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006377#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006378 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6379#endif
6380#ifdef HAVE_TEMPNAM
6381 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6382#endif
6383#ifdef HAVE_TMPNAM
6384 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6385#endif
Fred Drakec9680921999-12-13 16:37:25 +00006386#ifdef HAVE_CONFSTR
6387 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6388#endif
6389#ifdef HAVE_SYSCONF
6390 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6391#endif
6392#ifdef HAVE_FPATHCONF
6393 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6394#endif
6395#ifdef HAVE_PATHCONF
6396 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6397#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006398 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00006399#ifdef MS_WIN32
6400 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6401#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006402 {NULL, NULL} /* Sentinel */
6403};
6404
6405
Barry Warsaw4a342091996-12-19 23:50:02 +00006406static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006407ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006408{
6409 PyObject* v = PyInt_FromLong(value);
6410 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
6411 return -1; /* triggers fatal error */
6412
6413 Py_DECREF(v);
6414 return 0;
6415}
6416
Guido van Rossumd48f2521997-12-05 22:19:34 +00006417#if defined(PYOS_OS2)
6418/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
6419static int insertvalues(PyObject *d)
6420{
6421 APIRET rc;
6422 ULONG values[QSV_MAX+1];
6423 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006424 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006425
6426 Py_BEGIN_ALLOW_THREADS
6427 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6428 Py_END_ALLOW_THREADS
6429
6430 if (rc != NO_ERROR) {
6431 os2_error(rc);
6432 return -1;
6433 }
6434
6435 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6436 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
6437 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6438 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6439 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6440 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
6441 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
6442
6443 switch (values[QSV_VERSION_MINOR]) {
6444 case 0: ver = "2.00"; break;
6445 case 10: ver = "2.10"; break;
6446 case 11: ver = "2.11"; break;
6447 case 30: ver = "3.00"; break;
6448 case 40: ver = "4.00"; break;
6449 case 50: ver = "5.00"; break;
6450 default:
Tim Peters885d4572001-11-28 20:27:42 +00006451 PyOS_snprintf(tmp, sizeof(tmp),
6452 "%d-%d", values[QSV_VERSION_MAJOR],
6453 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006454 ver = &tmp[0];
6455 }
6456
6457 /* Add Indicator of the Version of the Operating System */
6458 v = PyString_FromString(ver);
6459 if (!v || PyDict_SetItemString(d, "version", v) < 0)
6460 return -1;
6461 Py_DECREF(v);
6462
6463 /* Add Indicator of Which Drive was Used to Boot the System */
6464 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6465 tmp[1] = ':';
6466 tmp[2] = '\0';
6467
6468 v = PyString_FromString(tmp);
6469 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
6470 return -1;
6471 Py_DECREF(v);
6472
6473 return 0;
6474}
6475#endif
6476
Barry Warsaw4a342091996-12-19 23:50:02 +00006477static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006478all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006479{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006480#ifdef F_OK
6481 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006482#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006483#ifdef R_OK
6484 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006485#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006486#ifdef W_OK
6487 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006488#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006489#ifdef X_OK
6490 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006491#endif
Fred Drakec9680921999-12-13 16:37:25 +00006492#ifdef NGROUPS_MAX
6493 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6494#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006495#ifdef TMP_MAX
6496 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6497#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006498#ifdef WNOHANG
6499 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006500#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006501#ifdef O_RDONLY
6502 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6503#endif
6504#ifdef O_WRONLY
6505 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6506#endif
6507#ifdef O_RDWR
6508 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6509#endif
6510#ifdef O_NDELAY
6511 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6512#endif
6513#ifdef O_NONBLOCK
6514 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6515#endif
6516#ifdef O_APPEND
6517 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6518#endif
6519#ifdef O_DSYNC
6520 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6521#endif
6522#ifdef O_RSYNC
6523 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6524#endif
6525#ifdef O_SYNC
6526 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6527#endif
6528#ifdef O_NOCTTY
6529 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6530#endif
6531#ifdef O_CREAT
6532 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6533#endif
6534#ifdef O_EXCL
6535 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6536#endif
6537#ifdef O_TRUNC
6538 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6539#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006540#ifdef O_BINARY
6541 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6542#endif
6543#ifdef O_TEXT
6544 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6545#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006546#ifdef O_LARGEFILE
6547 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6548#endif
6549
Tim Peters5aa91602002-01-30 05:46:57 +00006550/* MS Windows */
6551#ifdef O_NOINHERIT
6552 /* Don't inherit in child processes. */
6553 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6554#endif
6555#ifdef _O_SHORT_LIVED
6556 /* Optimize for short life (keep in memory). */
6557 /* MS forgot to define this one with a non-underscore form too. */
6558 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6559#endif
6560#ifdef O_TEMPORARY
6561 /* Automatically delete when last handle is closed. */
6562 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6563#endif
6564#ifdef O_RANDOM
6565 /* Optimize for random access. */
6566 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6567#endif
6568#ifdef O_SEQUENTIAL
6569 /* Optimize for sequential access. */
6570 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6571#endif
6572
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006573/* GNU extensions. */
6574#ifdef O_DIRECT
6575 /* Direct disk access. */
6576 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6577#endif
6578#ifdef O_DIRECTORY
6579 /* Must be a directory. */
6580 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6581#endif
6582#ifdef O_NOFOLLOW
6583 /* Do not follow links. */
6584 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6585#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006586
Guido van Rossum246bc171999-02-01 23:54:31 +00006587#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006588#if defined(PYOS_OS2) && defined(PYCC_GCC)
6589 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6590 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6591 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6592 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6593 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6594 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6595 if (ins(d, "P_PM", (long)P_PM)) return -1;
6596 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6597 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6598 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6599 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6600 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6601 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6602 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6603 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6604 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6605 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6606 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6607 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6608 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6609#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006610 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6611 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6612 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6613 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6614 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006615#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006616#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006617
Guido van Rossumd48f2521997-12-05 22:19:34 +00006618#if defined(PYOS_OS2)
6619 if (insertvalues(d)) return -1;
6620#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006621 return 0;
6622}
6623
6624
Tim Peters5aa91602002-01-30 05:46:57 +00006625#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006626#define INITFUNC initnt
6627#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006628
6629#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006630#define INITFUNC initos2
6631#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006632
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006633#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006634#define INITFUNC initposix
6635#define MODNAME "posix"
6636#endif
6637
Guido van Rossum3886bb61998-12-04 18:50:17 +00006638DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006639INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006640{
Barry Warsaw53699e91996-12-10 23:23:01 +00006641 PyObject *m, *d, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006642
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006643 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006644 posix_methods,
6645 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006646 (PyObject *)NULL,
6647 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00006648 d = PyModule_GetDict(m);
Tim Peters5aa91602002-01-30 05:46:57 +00006649
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006650 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006651 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00006652 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006653 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006654 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006655
Barry Warsaw4a342091996-12-19 23:50:02 +00006656 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00006657 return;
6658
Fred Drakebec628d1999-12-15 18:31:10 +00006659 if (setup_confname_tables(d))
6660 return;
6661
Barry Warsawca74da41999-02-09 19:31:45 +00006662 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006663
Guido van Rossumb3d39562000-01-31 18:41:26 +00006664#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006665 if (posix_putenv_garbage == NULL)
6666 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006667#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006668
Guido van Rossum14648392001-12-08 18:02:58 +00006669 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006670 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
6671 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
6672
Guido van Rossum14648392001-12-08 18:02:58 +00006673 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006674 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Guido van Rossumbb2501f2001-12-27 16:23:28 +00006675 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006676}