blob: aa9244a07c15929b5afc5da64d122df2588d9dd6 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +00007 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000016static char posix__doc__ [] =
17"This module provides access to operating system functionality that is\n\
18standardized by the C Standard and the POSIX standard (a thinly\n\
19disguised Unix interface). Refer to the library manual and\n\
20corresponding Unix manual entries for more information on calls.";
21
Barry Warsaw53699e91996-12-10 23:23:01 +000022#include "Python.h"
Guido van Rossum98bf58f2001-10-18 20:34:25 +000023#include "structseq.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000024
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000025#if defined(PYOS_OS2)
26#define INCL_DOS
27#define INCL_DOSERRORS
28#define INCL_DOSPROCESS
29#define INCL_NOPMAPI
30#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000031#if defined(PYCC_GCC)
32#include <ctype.h>
33#include <io.h>
34#include <stdio.h>
35#include <process.h>
36#include "osdefs.h"
37#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000038#endif
39
Guido van Rossumb6775db1994-08-01 11:34:53 +000040#include <sys/types.h>
41#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000042
Guido van Rossum36bc6801995-06-14 22:54:23 +000043#ifdef HAVE_SYS_WAIT_H
44#include <sys/wait.h> /* For WNOHANG */
45#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000046
Guido van Rossuma376cc51996-12-05 23:43:35 +000047#ifdef HAVE_SIGNAL_H
48#include <signal.h>
49#endif
50
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#ifdef HAVE_FCNTL_H
52#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000053#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000054
Guido van Rossuma6535fd2001-10-18 19:44:10 +000055#ifdef HAVE_GRP_H
56#include <grp.h>
57#endif
58
Guido van Rossuma4916fa1996-05-23 22:58:55 +000059/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000060/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000062#include <process.h>
63#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000064#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000065#define HAVE_GETCWD 1
66#define HAVE_OPENDIR 1
67#define HAVE_SYSTEM 1
68#if defined(__OS2__)
69#define HAVE_EXECV 1
70#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000071#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072#include <process.h>
73#else
74#ifdef __BORLANDC__ /* Borland compiler */
75#define HAVE_EXECV 1
76#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#define HAVE_OPENDIR 1
78#define HAVE_PIPE 1
79#define HAVE_POPEN 1
80#define HAVE_SYSTEM 1
81#define HAVE_WAIT 1
82#else
83#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000084#define HAVE_GETCWD 1
85#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000086#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000087#define HAVE_EXECV 1
88#define HAVE_PIPE 1
89#define HAVE_POPEN 1
90#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000091#define HAVE_CWAIT 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000093#endif /* !MS_WIN32 */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000094#else
95#if defined(PYOS_OS2) && defined(PYCC_GCC)
96/* Everything needed is defined in PC/os2emx/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000097#else /* all other compilers */
98/* Unix functions that the configure script doesn't check for */
99#define HAVE_EXECV 1
100#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000101#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
102#define HAVE_FORK1 1
103#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000104#define HAVE_GETCWD 1
105#define HAVE_GETEGID 1
106#define HAVE_GETEUID 1
107#define HAVE_GETGID 1
108#define HAVE_GETPPID 1
109#define HAVE_GETUID 1
110#define HAVE_KILL 1
111#define HAVE_OPENDIR 1
112#define HAVE_PIPE 1
113#define HAVE_POPEN 1
114#define HAVE_SYSTEM 1
115#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000116#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000117#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#endif /* _MSC_VER */
119#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000120#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000121#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000122
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000123#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000124
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000125#if defined(sun) && !defined(__SVR4)
126/* SunOS 4.1.4 doesn't have prototypes for these: */
127extern int rename(const char *, const char *);
128extern int pclose(FILE *);
129extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000130extern int fsync(int);
131extern int lstat(const char *, struct stat *);
132extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000133#endif
134
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000135#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000136#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000138#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000139#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000142extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000144#endif
145#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(char *);
147extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(const char *);
150extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000152#ifdef __BORLANDC__
153extern int chmod(const char *, int);
154#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000156#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int chown(const char *, uid_t, gid_t);
158extern char *getcwd(char *, int);
159extern char *strerror(int);
160extern int link(const char *, const char *);
161extern int rename(const char *, const char *);
162extern int stat(const char *, struct stat *);
163extern int unlink(const char *);
164extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000167#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000170#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000172
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175#ifdef HAVE_UTIME_H
176#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000177#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000179#ifdef HAVE_SYS_UTIME_H
180#include <sys/utime.h>
181#define HAVE_UTIME_H /* pretend we do for the rest of this file */
182#endif /* HAVE_SYS_UTIME_H */
183
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184#ifdef HAVE_SYS_TIMES_H
185#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000186#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187
188#ifdef HAVE_SYS_PARAM_H
189#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000190#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000191
192#ifdef HAVE_SYS_UTSNAME_H
193#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000194#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000196#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000198#define NAMLEN(dirent) strlen((dirent)->d_name)
199#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000200#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#include <direct.h>
202#define NAMLEN(dirent) strlen((dirent)->d_name)
203#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000206#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000207#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#include <direct.h>
220#include <io.h>
221#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000222#include "osdefs.h"
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000223#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000225#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000227#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#else /* 16-bit Windows */
229#include <dos.h>
230#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000231#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233
Guido van Rossumd48f2521997-12-05 22:19:34 +0000234#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000236#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
Tim Petersbc2e10e2002-03-03 23:17:02 +0000238#ifndef MAXPATHLEN
239#define MAXPATHLEN 1024
240#endif /* MAXPATHLEN */
241
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000242#ifdef UNION_WAIT
243/* Emulate some macros on systems that have a union instead of macros */
244
245#ifndef WIFEXITED
246#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
247#endif
248
249#ifndef WEXITSTATUS
250#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
251#endif
252
253#ifndef WTERMSIG
254#define WTERMSIG(u_wait) ((u_wait).w_termsig)
255#endif
256
257#endif /* UNION_WAIT */
258
Greg Wardb48bc172000-03-01 21:51:56 +0000259/* Don't use the "_r" form if we don't need it (also, won't have a
260 prototype for it, at least on Solaris -- maybe others as well?). */
261#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
262#define USE_CTERMID_R
263#endif
264
265#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
266#define USE_TMPNAM_R
267#endif
268
Fred Drake699f3522000-06-29 21:12:41 +0000269/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000270#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000271#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000272# define STAT _stati64
273# define FSTAT _fstati64
274# define STRUCT_STAT struct _stati64
275#else
276# define STAT stat
277# define FSTAT fstat
278# define STRUCT_STAT struct stat
279#endif
280
281
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282/* Return a dictionary corresponding to the POSIX environment table */
283
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000284#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000286#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287
Barry Warsaw53699e91996-12-10 23:23:01 +0000288static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000289convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290{
Barry Warsaw53699e91996-12-10 23:23:01 +0000291 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000293 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 if (d == NULL)
295 return NULL;
296 if (environ == NULL)
297 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000298 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000300 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000301 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 char *p = strchr(*e, '=');
303 if (p == NULL)
304 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000305 k = PyString_FromStringAndSize(*e, (int)(p-*e));
306 if (k == NULL) {
307 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000309 }
310 v = PyString_FromString(p+1);
311 if (v == NULL) {
312 PyErr_Clear();
313 Py_DECREF(k);
314 continue;
315 }
316 if (PyDict_GetItem(d, k) == NULL) {
317 if (PyDict_SetItem(d, k, v) != 0)
318 PyErr_Clear();
319 }
320 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000321 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000323#if defined(PYOS_OS2)
324 {
325 APIRET rc;
326 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
327
328 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000329 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000330 PyObject *v = PyString_FromString(buffer);
331 PyDict_SetItemString(d, "BEGINLIBPATH", v);
332 Py_DECREF(v);
333 }
334 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
335 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
336 PyObject *v = PyString_FromString(buffer);
337 PyDict_SetItemString(d, "ENDLIBPATH", v);
338 Py_DECREF(v);
339 }
340 }
341#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342 return d;
343}
344
345
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346/* Set a POSIX-specific error from errno, and return NULL */
347
Barry Warsawd58d7641998-07-23 16:14:40 +0000348static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000349posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000350{
Barry Warsawca74da41999-02-09 19:31:45 +0000351 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000352}
Barry Warsawd58d7641998-07-23 16:14:40 +0000353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000354posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000355{
Barry Warsawca74da41999-02-09 19:31:45 +0000356 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000357}
358
Mark Hammondef8b6542001-05-13 08:04:26 +0000359static PyObject *
360posix_error_with_allocated_filename(char* name)
361{
362 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
363 PyMem_Free(name);
364 return rc;
365}
366
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000367#ifdef MS_WIN32
368static PyObject *
369win32_error(char* function, char* filename)
370{
Mark Hammond33a6da92000-08-15 00:46:38 +0000371 /* XXX We should pass the function name along in the future.
372 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000373 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000374 Windows error object, which is non-trivial.
375 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000376 errno = GetLastError();
377 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000378 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000379 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000380 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000381}
382#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000383
Guido van Rossumd48f2521997-12-05 22:19:34 +0000384#if defined(PYOS_OS2)
385/**********************************************************************
386 * Helper Function to Trim and Format OS/2 Messages
387 **********************************************************************/
388 static void
389os2_formatmsg(char *msgbuf, int msglen, char *reason)
390{
391 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
392
393 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
394 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
395
396 while (lastc > msgbuf && isspace(*lastc))
397 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
398 }
399
400 /* Add Optional Reason Text */
401 if (reason) {
402 strcat(msgbuf, " : ");
403 strcat(msgbuf, reason);
404 }
405}
406
407/**********************************************************************
408 * Decode an OS/2 Operating System Error Code
409 *
410 * A convenience function to lookup an OS/2 error code and return a
411 * text message we can use to raise a Python exception.
412 *
413 * Notes:
414 * The messages for errors returned from the OS/2 kernel reside in
415 * the file OSO001.MSG in the \OS2 directory hierarchy.
416 *
417 **********************************************************************/
418 static char *
419os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
420{
421 APIRET rc;
422 ULONG msglen;
423
424 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
425 Py_BEGIN_ALLOW_THREADS
426 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
427 errorcode, "oso001.msg", &msglen);
428 Py_END_ALLOW_THREADS
429
430 if (rc == NO_ERROR)
431 os2_formatmsg(msgbuf, msglen, reason);
432 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000433 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000434 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000435
436 return msgbuf;
437}
438
439/* Set an OS/2-specific error and return NULL. OS/2 kernel
440 errors are not in a global variable e.g. 'errno' nor are
441 they congruent with posix error numbers. */
442
443static PyObject * os2_error(int code)
444{
445 char text[1024];
446 PyObject *v;
447
448 os2_strerror(text, sizeof(text), code, "");
449
450 v = Py_BuildValue("(is)", code, text);
451 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000452 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000453 Py_DECREF(v);
454 }
455 return NULL; /* Signal to Python that an Exception is Pending */
456}
457
458#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459
460/* POSIX generic methods */
461
Barry Warsaw53699e91996-12-10 23:23:01 +0000462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000463posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000464{
465 int fd;
466 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000467 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000468 return NULL;
469 Py_BEGIN_ALLOW_THREADS
470 res = (*func)(fd);
471 Py_END_ALLOW_THREADS
472 if (res < 0)
473 return posix_error();
474 Py_INCREF(Py_None);
475 return Py_None;
476}
477
478
479static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000480posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481{
Mark Hammondef8b6542001-05-13 08:04:26 +0000482 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000483 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000484 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000485 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000487 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000488 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000489 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000491 return posix_error_with_allocated_filename(path1);
492 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000493 Py_INCREF(Py_None);
494 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000495}
496
Barry Warsaw53699e91996-12-10 23:23:01 +0000497static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000498posix_2str(PyObject *args, char *format,
499 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500{
Mark Hammondef8b6542001-05-13 08:04:26 +0000501 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000502 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000503 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000504 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000505 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000506 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000507 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000508 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000509 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000510 PyMem_Free(path1);
511 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000512 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000513 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000515 Py_INCREF(Py_None);
516 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517}
518
Tim Peters5aa91602002-01-30 05:46:57 +0000519static char stat_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000520"stat_result: Result from stat or lstat.\n\n\
521This object may be accessed either as a tuple of\n\
522 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
523or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
524\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000525Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000526they are available as attributes only.\n\
527\n\
528See os.stat for more information.\n";
529
530static PyStructSequence_Field stat_result_fields[] = {
531 {"st_mode", "protection bits"},
532 {"st_ino", "inode"},
533 {"st_dev", "device"},
534 {"st_nlink", "number of hard links"},
535 {"st_uid", "user ID of owner"},
536 {"st_gid", "group ID of owner"},
537 {"st_size", "total size, in bytes"},
538 {"st_atime", "time of last access"},
539 {"st_mtime", "time of last modification"},
540 {"st_ctime", "time of last change"},
541#ifdef HAVE_ST_BLKSIZE
542 {"st_blksize", "blocksize for filesystem I/O"},
543#endif
544#ifdef HAVE_ST_BLOCKS
545 {"st_blocks", "number of blocks allocated"},
546#endif
547#ifdef HAVE_ST_RDEV
548 {"st_rdev", "device type (if inode device)"},
549#endif
550 {0}
551};
552
553#ifdef HAVE_ST_BLKSIZE
554#define ST_BLKSIZE_IDX 10
555#else
556#define ST_BLKSIZE_IDX 9
557#endif
558
559#ifdef HAVE_ST_BLOCKS
560#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
561#else
562#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
563#endif
564
565#ifdef HAVE_ST_RDEV
566#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
567#else
568#define ST_RDEV_IDX ST_BLOCKS_IDX
569#endif
570
571static PyStructSequence_Desc stat_result_desc = {
572 "stat_result", /* name */
573 stat_result__doc__, /* doc */
574 stat_result_fields,
575 10
576};
577
Tim Peters5aa91602002-01-30 05:46:57 +0000578static char statvfs_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000579"statvfs_result: Result from statvfs or fstatvfs.\n\n\
580This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000581 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
582or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000583\n\
584See os.statvfs for more information.\n";
585
586static PyStructSequence_Field statvfs_result_fields[] = {
587 {"f_bsize", },
588 {"f_frsize", },
589 {"f_blocks", },
590 {"f_bfree", },
591 {"f_bavail", },
592 {"f_files", },
593 {"f_ffree", },
594 {"f_favail", },
595 {"f_flag", },
596 {"f_namemax",},
597 {0}
598};
599
600static PyStructSequence_Desc statvfs_result_desc = {
601 "statvfs_result", /* name */
602 statvfs_result__doc__, /* doc */
603 statvfs_result_fields,
604 10
605};
606
607static PyTypeObject StatResultType;
608static PyTypeObject StatVFSResultType;
609
Tim Peters5aa91602002-01-30 05:46:57 +0000610/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000611 (used by posix_stat() and posix_fstat()) */
612static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000613_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000614{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000615 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000616 if (v == NULL)
617 return NULL;
618
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000619 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000620#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000621 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000622 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000623#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000624 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000625#endif
626#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000627 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000628 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000629#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000630 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000631#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000632 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
633 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
634 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000635#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000636 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000637 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000638#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000639 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000640#endif
641#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000642 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000643 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000644 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000645 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000646 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000647 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000648#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000649 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
650 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
651 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
652#endif
653
654#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000655 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000656 PyInt_FromLong((long)st.st_blksize));
657#endif
658#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000659 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000660 PyInt_FromLong((long)st.st_blocks));
661#endif
662#ifdef HAVE_ST_RDEV
663 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
664 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000665#endif
666
667 if (PyErr_Occurred()) {
668 Py_DECREF(v);
669 return NULL;
670 }
671
672 return v;
673}
674
Barry Warsaw53699e91996-12-10 23:23:01 +0000675static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000676posix_do_stat(PyObject *self, PyObject *args, char *format,
677 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000678{
Fred Drake699f3522000-06-29 21:12:41 +0000679 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000680 char *path = NULL; /* pass this to stat; do not free() it */
681 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000682 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000683
684#ifdef MS_WIN32
Tim Peters500bd032001-12-19 19:05:01 +0000685 int pathlen;
686 char pathcopy[MAX_PATH];
Guido van Rossumace88ae2000-04-21 18:54:45 +0000687#endif /* MS_WIN32 */
688
Tim Peters5aa91602002-01-30 05:46:57 +0000689 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000690 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000692 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000693
694#ifdef MS_WIN32
695 pathlen = strlen(path);
696 /* the library call can blow up if the file name is too long! */
697 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000698 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000699 errno = ENAMETOOLONG;
700 return posix_error();
701 }
702
Tim Peters500bd032001-12-19 19:05:01 +0000703 /* Remove trailing slash or backslash, unless it's the current
704 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
705 */
706 if (pathlen > 0 &&
707 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
708 /* It does end with a slash -- exempt the root drive cases. */
709 /* XXX UNC root drives should also be exempted? */
710 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
711 /* leave it alone */;
712 else {
713 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000714 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000715 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000716 path = pathcopy;
717 }
718 }
719#endif /* MS_WIN32 */
720
Barry Warsaw53699e91996-12-10 23:23:01 +0000721 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000722 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000723 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000724 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000725 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000726
Tim Peters500bd032001-12-19 19:05:01 +0000727 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000728 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000729}
730
731
732/* POSIX methods */
733
Guido van Rossum94f6f721999-01-06 18:42:14 +0000734static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000735"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000736Test for access to a file.";
737
738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000739posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000740{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000741 char *path;
742 int mode;
743 int res;
744
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000745 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000746 return NULL;
747 Py_BEGIN_ALLOW_THREADS
748 res = access(path, mode);
749 Py_END_ALLOW_THREADS
750 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000751}
752
Guido van Rossumd371ff11999-01-25 16:12:23 +0000753#ifndef F_OK
754#define F_OK 0
755#endif
756#ifndef R_OK
757#define R_OK 4
758#endif
759#ifndef W_OK
760#define W_OK 2
761#endif
762#ifndef X_OK
763#define X_OK 1
764#endif
765
766#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000767static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000768"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000769Return the name of the terminal device connected to 'fd'.";
770
771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000772posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000773{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000774 int id;
775 char *ret;
776
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000777 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000778 return NULL;
779
Guido van Rossum94f6f721999-01-06 18:42:14 +0000780 ret = ttyname(id);
781 if (ret == NULL)
782 return(posix_error());
783 return(PyString_FromString(ret));
784}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000785#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000786
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000787#ifdef HAVE_CTERMID
788static char posix_ctermid__doc__[] =
789"ctermid() -> String\n\
790Return the name of the controlling terminal for this process.";
791
792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000793posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000794{
795 char *ret;
796 char buffer[L_ctermid];
797
798 if (!PyArg_ParseTuple(args, ":ctermid"))
799 return NULL;
800
Greg Wardb48bc172000-03-01 21:51:56 +0000801#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000802 ret = ctermid_r(buffer);
803#else
804 ret = ctermid(buffer);
805#endif
806 if (ret == NULL)
807 return(posix_error());
808 return(PyString_FromString(buffer));
809}
810#endif
811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000812static char posix_chdir__doc__[] =
813"chdir(path) -> None\n\
814Change the current working directory to the specified path.";
815
Barry Warsaw53699e91996-12-10 23:23:01 +0000816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000817posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000819#if defined(PYOS_OS2) && defined(PYCC_GCC)
820 return posix_1str(args, "et:chdir", _chdir2);
821#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000822 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000823#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824}
825
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000826
827static char posix_chmod__doc__[] =
828"chmod(path, mode) -> None\n\
829Change the access permissions of a file.";
830
Barry Warsaw53699e91996-12-10 23:23:01 +0000831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000832posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000833{
Mark Hammondef8b6542001-05-13 08:04:26 +0000834 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000835 int i;
836 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000837 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000838 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000839 return NULL;
840 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000841 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000842 Py_END_ALLOW_THREADS
843 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000844 return posix_error_with_allocated_filename(path);
845 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000846 Py_INCREF(Py_None);
847 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000848}
849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000850
Martin v. Löwis244edc82001-10-04 22:44:26 +0000851#ifdef HAVE_CHROOT
Tim Peters5aa91602002-01-30 05:46:57 +0000852static char posix_chroot__doc__[] =
Martin v. Löwis244edc82001-10-04 22:44:26 +0000853"chroot(path) -> None\n\
854Change root directory to path.";
855
856static PyObject *
857posix_chroot(PyObject *self, PyObject *args)
858{
859 return posix_1str(args, "et:chroot", chroot);
860}
861#endif
862
Guido van Rossum21142a01999-01-08 21:05:37 +0000863#ifdef HAVE_FSYNC
864static char posix_fsync__doc__[] =
865"fsync(fildes) -> None\n\
866force write of file with filedescriptor to disk.";
867
868static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000869posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000870{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000871 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000872}
873#endif /* HAVE_FSYNC */
874
875#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000876
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000877#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000878extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
879#endif
880
Guido van Rossum21142a01999-01-08 21:05:37 +0000881static char posix_fdatasync__doc__[] =
882"fdatasync(fildes) -> None\n\
883force write of file with filedescriptor to disk.\n\
884 does not force update of metadata.";
885
886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000887posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000888{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000889 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000890}
891#endif /* HAVE_FDATASYNC */
892
893
Fredrik Lundh10723342000-07-10 16:38:09 +0000894#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000895static char posix_chown__doc__[] =
896"chown(path, uid, gid) -> None\n\
897Change the owner and group id of path to the numeric uid and gid.";
898
Barry Warsaw53699e91996-12-10 23:23:01 +0000899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000900posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000901{
Mark Hammondef8b6542001-05-13 08:04:26 +0000902 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000903 int uid, gid;
904 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000905 if (!PyArg_ParseTuple(args, "etii:chown",
906 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000907 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000908 return NULL;
909 Py_BEGIN_ALLOW_THREADS
910 res = chown(path, (uid_t) uid, (gid_t) gid);
911 Py_END_ALLOW_THREADS
912 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000913 return posix_error_with_allocated_filename(path);
914 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000915 Py_INCREF(Py_None);
916 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000917}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000918#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000919
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000920
Guido van Rossum36bc6801995-06-14 22:54:23 +0000921#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000922static char posix_getcwd__doc__[] =
923"getcwd() -> path\n\
924Return a string representing the current working directory.";
925
Barry Warsaw53699e91996-12-10 23:23:01 +0000926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000927posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000928{
929 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000930 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000931 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000932 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000933 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000934#if defined(PYOS_OS2) && defined(PYCC_GCC)
935 res = _getcwd2(buf, sizeof buf);
936#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000937 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000938#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000939 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000940 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000941 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000942 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000943}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000944#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000946
Guido van Rossumb6775db1994-08-01 11:34:53 +0000947#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000948static char posix_link__doc__[] =
949"link(src, dst) -> None\n\
950Create a hard link to a file.";
951
Barry Warsaw53699e91996-12-10 23:23:01 +0000952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000953posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954{
Mark Hammondef8b6542001-05-13 08:04:26 +0000955 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000957#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000959
960static char posix_listdir__doc__[] =
961"listdir(path) -> list_of_strings\n\
962Return a list containing the names of the entries in the directory.\n\
963\n\
964 path: path of directory to list\n\
965\n\
966The list is in arbitrary order. It does not include the special\n\
967entries '.' and '..' even if they are present in the directory.";
968
Barry Warsaw53699e91996-12-10 23:23:01 +0000969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000970posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000971{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000972 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000973 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000974#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000975
Barry Warsaw53699e91996-12-10 23:23:01 +0000976 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000977 HANDLE hFindFile;
978 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000979 /* MAX_PATH characters could mean a bigger encoded string */
980 char namebuf[MAX_PATH*2+5];
981 char *bufptr = namebuf;
982 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000983 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000984
Tim Peters5aa91602002-01-30 05:46:57 +0000985 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +0000986 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000987 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000988 ch = namebuf[len-1];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000989 if (ch != SEP && ch != ALTSEP && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000990 namebuf[len++] = '/';
991 strcpy(namebuf + len, "*.*");
992
Barry Warsaw53699e91996-12-10 23:23:01 +0000993 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000994 return NULL;
995
996 hFindFile = FindFirstFile(namebuf, &FileData);
997 if (hFindFile == INVALID_HANDLE_VALUE) {
998 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000999 if (errno == ERROR_FILE_NOT_FOUND)
1000 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001001 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001002 }
1003 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001004 if (FileData.cFileName[0] == '.' &&
1005 (FileData.cFileName[1] == '\0' ||
1006 FileData.cFileName[1] == '.' &&
1007 FileData.cFileName[2] == '\0'))
1008 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001009 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001010 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001011 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001012 d = NULL;
1013 break;
1014 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001015 if (PyList_Append(d, v) != 0) {
1016 Py_DECREF(v);
1017 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001018 d = NULL;
1019 break;
1020 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001021 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001022 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1023
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001024 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001025 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001026
1027 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001028
Tim Peters0bb44a42000-09-15 07:44:49 +00001029#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001030
1031#ifndef MAX_PATH
1032#define MAX_PATH 250
1033#endif
1034 char *name, *pt;
1035 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001036 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001037 char namebuf[MAX_PATH+5];
1038 struct _find_t ep;
1039
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001040 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001041 return NULL;
1042 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001043 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001044 return NULL;
1045 }
1046 strcpy(namebuf, name);
1047 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001048 if (*pt == ALTSEP)
1049 *pt = SEP;
1050 if (namebuf[len-1] != SEP)
1051 namebuf[len++] = SEP;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001052 strcpy(namebuf + len, "*.*");
1053
Barry Warsaw53699e91996-12-10 23:23:01 +00001054 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001055 return NULL;
1056
1057 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001058 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1059 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001060 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001061 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001062 }
1063 do {
1064 if (ep.name[0] == '.' &&
1065 (ep.name[1] == '\0' ||
1066 ep.name[1] == '.' &&
1067 ep.name[2] == '\0'))
1068 continue;
1069 strcpy(namebuf, ep.name);
1070 for (pt = namebuf; *pt; pt++)
1071 if (isupper(*pt))
1072 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001073 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001074 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001075 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001076 d = NULL;
1077 break;
1078 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001079 if (PyList_Append(d, v) != 0) {
1080 Py_DECREF(v);
1081 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001082 d = NULL;
1083 break;
1084 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001085 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001086 } while (_dos_findnext(&ep) == 0);
1087
1088 return d;
1089
Tim Peters0bb44a42000-09-15 07:44:49 +00001090#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001091
1092#ifndef MAX_PATH
1093#define MAX_PATH CCHMAXPATH
1094#endif
1095 char *name, *pt;
1096 int len;
1097 PyObject *d, *v;
1098 char namebuf[MAX_PATH+5];
1099 HDIR hdir = 1;
1100 ULONG srchcnt = 1;
1101 FILEFINDBUF3 ep;
1102 APIRET rc;
1103
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001104 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001105 return NULL;
1106 if (len >= MAX_PATH) {
1107 PyErr_SetString(PyExc_ValueError, "path too long");
1108 return NULL;
1109 }
1110 strcpy(namebuf, name);
1111 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001112 if (*pt == ALTSEP)
1113 *pt = SEP;
1114 if (namebuf[len-1] != SEP)
1115 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001116 strcpy(namebuf + len, "*.*");
1117
1118 if ((d = PyList_New(0)) == NULL)
1119 return NULL;
1120
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001121 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1122 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001123 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001124 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1125 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1126 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001127
1128 if (rc != NO_ERROR) {
1129 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001130 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001131 }
1132
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001133 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001134 do {
1135 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001136 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001137 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001138
1139 strcpy(namebuf, ep.achName);
1140
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001141 /* Leave Case of Name Alone -- In Native Form */
1142 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001143
1144 v = PyString_FromString(namebuf);
1145 if (v == NULL) {
1146 Py_DECREF(d);
1147 d = NULL;
1148 break;
1149 }
1150 if (PyList_Append(d, v) != 0) {
1151 Py_DECREF(v);
1152 Py_DECREF(d);
1153 d = NULL;
1154 break;
1155 }
1156 Py_DECREF(v);
1157 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1158 }
1159
1160 return d;
1161#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001162
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001163 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001164 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001165 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001166 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001167 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001169 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001170 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001171 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001172 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001173 closedir(dirp);
1174 return NULL;
1175 }
1176 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001177 if (ep->d_name[0] == '.' &&
1178 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001179 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001180 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001181 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001183 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184 d = NULL;
1185 break;
1186 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001187 if (PyList_Append(d, v) != 0) {
1188 Py_DECREF(v);
1189 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001190 d = NULL;
1191 break;
1192 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001193 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001194 }
1195 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001196
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001197 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001198
Tim Peters0bb44a42000-09-15 07:44:49 +00001199#endif /* which OS */
1200} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001201
Mark Hammondef8b6542001-05-13 08:04:26 +00001202#ifdef MS_WIN32
1203/* A helper function for abspath on win32 */
1204static PyObject *
1205posix__getfullpathname(PyObject *self, PyObject *args)
1206{
1207 /* assume encoded strings wont more than double no of chars */
1208 char inbuf[MAX_PATH*2];
1209 char *inbufp = inbuf;
1210 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1211 char outbuf[MAX_PATH*2];
1212 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001213 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1214 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001215 &insize))
1216 return NULL;
1217 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1218 outbuf, &temp))
1219 return win32_error("GetFullPathName", inbuf);
1220 return PyString_FromString(outbuf);
1221} /* end of posix__getfullpathname */
1222#endif /* MS_WIN32 */
1223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001224static char posix_mkdir__doc__[] =
1225"mkdir(path [, mode=0777]) -> None\n\
1226Create a directory.";
1227
Barry Warsaw53699e91996-12-10 23:23:01 +00001228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001229posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001230{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001231 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001232 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001233 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001234 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001235 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001236 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001237 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001238#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001239 res = mkdir(path);
1240#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001241 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001242#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001243 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001244 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001245 return posix_error_with_allocated_filename(path);
1246 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001247 Py_INCREF(Py_None);
1248 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249}
1250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001251
Guido van Rossumb6775db1994-08-01 11:34:53 +00001252#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001253#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1254#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1255#include <sys/resource.h>
1256#endif
1257#endif
1258
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001259static char posix_nice__doc__[] =
1260"nice(inc) -> new_priority\n\
1261Decrease the priority of process and return new priority.";
1262
Barry Warsaw53699e91996-12-10 23:23:01 +00001263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001264posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001265{
1266 int increment, value;
1267
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001268 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001269 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001270
1271 /* There are two flavours of 'nice': one that returns the new
1272 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001273 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1274 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001275
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001276 If we are of the nice family that returns the new priority, we
1277 need to clear errno before the call, and check if errno is filled
1278 before calling posix_error() on a returnvalue of -1, because the
1279 -1 may be the actual new priority! */
1280
1281 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001282 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001283#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001284 if (value == 0)
1285 value = getpriority(PRIO_PROCESS, 0);
1286#endif
1287 if (value == -1 && errno != 0)
1288 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001289 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001290 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001291}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001292#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001294
1295static char posix_rename__doc__[] =
1296"rename(old, new) -> None\n\
1297Rename a file or directory.";
1298
Barry Warsaw53699e91996-12-10 23:23:01 +00001299static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001300posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301{
Mark Hammondef8b6542001-05-13 08:04:26 +00001302 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303}
1304
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001305
1306static char posix_rmdir__doc__[] =
1307"rmdir(path) -> None\n\
1308Remove a directory.";
1309
Barry Warsaw53699e91996-12-10 23:23:01 +00001310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001311posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312{
Mark Hammondef8b6542001-05-13 08:04:26 +00001313 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314}
1315
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001316
1317static char posix_stat__doc__[] =
1318"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1319Perform a stat system call on the given path.";
1320
Barry Warsaw53699e91996-12-10 23:23:01 +00001321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001322posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001323{
Mark Hammondef8b6542001-05-13 08:04:26 +00001324 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001325}
1326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001327
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001328#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001329static char posix_system__doc__[] =
1330"system(command) -> exit_status\n\
1331Execute the command (a string) in a subshell.";
1332
Barry Warsaw53699e91996-12-10 23:23:01 +00001333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001334posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001335{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001336 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001337 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001338 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001339 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001340 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001341 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001342 Py_END_ALLOW_THREADS
1343 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001345#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001347
1348static char posix_umask__doc__[] =
1349"umask(new_mask) -> old_mask\n\
1350Set the current numeric umask and return the previous umask.";
1351
Barry Warsaw53699e91996-12-10 23:23:01 +00001352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001353posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001354{
1355 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001356 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001358 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001359 if (i < 0)
1360 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001361 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362}
1363
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001364
1365static char posix_unlink__doc__[] =
1366"unlink(path) -> None\n\
1367Remove a file (same as remove(path)).";
1368
1369static char posix_remove__doc__[] =
1370"remove(path) -> None\n\
1371Remove a file (same as unlink(path)).";
1372
Barry Warsaw53699e91996-12-10 23:23:01 +00001373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001374posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001375{
Mark Hammondef8b6542001-05-13 08:04:26 +00001376 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001377}
1378
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001379
Guido van Rossumb6775db1994-08-01 11:34:53 +00001380#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001381static char posix_uname__doc__[] =
1382"uname() -> (sysname, nodename, release, version, machine)\n\
1383Return a tuple identifying the current operating system.";
1384
Barry Warsaw53699e91996-12-10 23:23:01 +00001385static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001386posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001387{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001388 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001389 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001390 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001391 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001392 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001393 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001394 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001395 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001396 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001397 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001398 u.sysname,
1399 u.nodename,
1400 u.release,
1401 u.version,
1402 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001403}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001404#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001405
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001406
1407static char posix_utime__doc__[] =
1408"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001409utime(path, None) -> None\n\
1410Set the access and modified time of the file to the given values. If the\n\
1411second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001412
Barry Warsaw53699e91996-12-10 23:23:01 +00001413static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001414posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001415{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001416 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001417 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001418 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001419 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001420
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001421/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001422#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001423 struct utimbuf buf;
1424#define ATIME buf.actime
1425#define MTIME buf.modtime
1426#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001427#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001428 time_t buf[2];
1429#define ATIME buf[0]
1430#define MTIME buf[1]
1431#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001432#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001433
Barry Warsaw3cef8562000-05-01 16:17:24 +00001434 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001435 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001436 if (arg == Py_None) {
1437 /* optional time values not given */
1438 Py_BEGIN_ALLOW_THREADS
1439 res = utime(path, NULL);
1440 Py_END_ALLOW_THREADS
1441 }
1442 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1443 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001444 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001445 return NULL;
1446 }
1447 else {
1448 ATIME = atime;
1449 MTIME = mtime;
1450 Py_BEGIN_ALLOW_THREADS
1451 res = utime(path, UTIME_ARG);
1452 Py_END_ALLOW_THREADS
1453 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001454 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001455 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001456 Py_INCREF(Py_None);
1457 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001458#undef UTIME_ARG
1459#undef ATIME
1460#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001461}
1462
Guido van Rossum85e3b011991-06-03 12:42:10 +00001463
Guido van Rossum3b066191991-06-04 19:40:25 +00001464/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001465
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001466static char posix__exit__doc__[] =
1467"_exit(status)\n\
1468Exit to the system with specified status, without normal exit processing.";
1469
Barry Warsaw53699e91996-12-10 23:23:01 +00001470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001471posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001472{
1473 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001474 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001475 return NULL;
1476 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001477 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001478}
1479
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001480
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001481#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001482static char posix_execv__doc__[] =
1483"execv(path, args)\n\
1484Execute an executable path with arguments, replacing current process.\n\
1485\n\
1486 path: path of executable file\n\
1487 args: tuple or list of strings";
1488
Barry Warsaw53699e91996-12-10 23:23:01 +00001489static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001490posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001491{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001492 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001493 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001494 char **argvlist;
1495 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001496 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001497
Guido van Rossum89b33251993-10-22 14:26:06 +00001498 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001499 argv is a list or tuple of strings. */
1500
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001501 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001502 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001503 if (PyList_Check(argv)) {
1504 argc = PyList_Size(argv);
1505 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001506 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001507 else if (PyTuple_Check(argv)) {
1508 argc = PyTuple_Size(argv);
1509 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001510 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001511 else {
Fred Drake661ea262000-10-24 19:57:45 +00001512 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001513 return NULL;
1514 }
1515
1516 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001517 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001518 return NULL;
1519 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001520
Barry Warsaw53699e91996-12-10 23:23:01 +00001521 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001522 if (argvlist == NULL)
1523 return NULL;
1524 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001525 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1526 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001527 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001528 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001529 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001530
Guido van Rossum85e3b011991-06-03 12:42:10 +00001531 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001532 }
1533 argvlist[argc] = NULL;
1534
Guido van Rossumb6775db1994-08-01 11:34:53 +00001535#ifdef BAD_EXEC_PROTOTYPES
1536 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001537#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001538 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001539#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001540
Guido van Rossum85e3b011991-06-03 12:42:10 +00001541 /* If we get here it's definitely an error */
1542
Barry Warsaw53699e91996-12-10 23:23:01 +00001543 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001544 return posix_error();
1545}
1546
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001547
1548static char posix_execve__doc__[] =
1549"execve(path, args, env)\n\
1550Execute a path with arguments and environment, replacing current process.\n\
1551\n\
1552 path: path of executable file\n\
1553 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001554 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001555
Barry Warsaw53699e91996-12-10 23:23:01 +00001556static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001557posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001558{
1559 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001560 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001561 char **argvlist;
1562 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001563 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001564 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001565 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001566
1567 /* execve has three arguments: (path, argv, env), where
1568 argv is a list or tuple of strings and env is a dictionary
1569 like posix.environ. */
1570
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001571 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001572 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001573 if (PyList_Check(argv)) {
1574 argc = PyList_Size(argv);
1575 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001576 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001577 else if (PyTuple_Check(argv)) {
1578 argc = PyTuple_Size(argv);
1579 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001580 }
1581 else {
Fred Drake661ea262000-10-24 19:57:45 +00001582 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001583 return NULL;
1584 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001585 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001586 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001587 return NULL;
1588 }
1589
Guido van Rossum50422b42000-04-26 20:34:28 +00001590 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001591 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001592 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001593 return NULL;
1594 }
1595
Barry Warsaw53699e91996-12-10 23:23:01 +00001596 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001597 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001598 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001599 return NULL;
1600 }
1601 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001602 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001603 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001604 &argvlist[i]))
1605 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001606 goto fail_1;
1607 }
1608 }
1609 argvlist[argc] = NULL;
1610
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001611 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001612 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001613 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001615 goto fail_1;
1616 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001617 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001618 keys = PyMapping_Keys(env);
1619 vals = PyMapping_Values(env);
1620 if (!keys || !vals)
1621 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001622
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001623 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001624 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001625 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001626
1627 key = PyList_GetItem(keys, pos);
1628 val = PyList_GetItem(vals, pos);
1629 if (!key || !val)
1630 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001631
Fred Drake661ea262000-10-24 19:57:45 +00001632 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1633 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001634 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001635 goto fail_2;
1636 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001637
1638#if defined(PYOS_OS2)
1639 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1640 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1641#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001642 len = PyString_Size(key) + PyString_Size(val) + 2;
1643 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001644 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001645 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001646 goto fail_2;
1647 }
Tim Petersc8996f52001-12-03 20:41:00 +00001648 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001649 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001650#if defined(PYOS_OS2)
1651 }
1652#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001653 }
1654 envlist[envc] = 0;
1655
Guido van Rossumb6775db1994-08-01 11:34:53 +00001656
1657#ifdef BAD_EXEC_PROTOTYPES
1658 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001659#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001660 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001661#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001662
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001663 /* If we get here it's definitely an error */
1664
1665 (void) posix_error();
1666
1667 fail_2:
1668 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001669 PyMem_DEL(envlist[envc]);
1670 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001671 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001672 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001673 Py_XDECREF(vals);
1674 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001675 return NULL;
1676}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001677#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001679
Guido van Rossuma1065681999-01-25 23:20:23 +00001680#ifdef HAVE_SPAWNV
1681static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001682"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001683Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001684\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001685 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001686 path: path of executable file\n\
1687 args: tuple or list of strings";
1688
1689static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001690posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001691{
1692 char *path;
1693 PyObject *argv;
1694 char **argvlist;
1695 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001696 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001697 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001698
1699 /* spawnv has three arguments: (mode, path, argv), where
1700 argv is a list or tuple of strings. */
1701
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001702 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001703 return NULL;
1704 if (PyList_Check(argv)) {
1705 argc = PyList_Size(argv);
1706 getitem = PyList_GetItem;
1707 }
1708 else if (PyTuple_Check(argv)) {
1709 argc = PyTuple_Size(argv);
1710 getitem = PyTuple_GetItem;
1711 }
1712 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001713 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001714 return NULL;
1715 }
1716
1717 argvlist = PyMem_NEW(char *, argc+1);
1718 if (argvlist == NULL)
1719 return NULL;
1720 for (i = 0; i < argc; i++) {
1721 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1722 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001723 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001724 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001725 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001726 }
1727 }
1728 argvlist[argc] = NULL;
1729
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001730#if defined(PYOS_OS2) && defined(PYCC_GCC)
1731 Py_BEGIN_ALLOW_THREADS
1732 spawnval = spawnv(mode, path, argvlist);
1733 Py_END_ALLOW_THREADS
1734#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001735 if (mode == _OLD_P_OVERLAY)
1736 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001737
Tim Peters25059d32001-12-07 20:35:43 +00001738 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001739 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001740 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001741#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001742
Guido van Rossuma1065681999-01-25 23:20:23 +00001743 PyMem_DEL(argvlist);
1744
Fred Drake699f3522000-06-29 21:12:41 +00001745 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001746 return posix_error();
1747 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001748#if SIZEOF_LONG == SIZEOF_VOID_P
1749 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001750#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001751 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001752#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001753}
1754
1755
1756static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001757"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001758Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001759\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001760 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001761 path: path of executable file\n\
1762 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001763 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001764
1765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001766posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001767{
1768 char *path;
1769 PyObject *argv, *env;
1770 char **argvlist;
1771 char **envlist;
1772 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1773 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001774 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001775 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001776
1777 /* spawnve has four arguments: (mode, path, argv, env), where
1778 argv is a list or tuple of strings and env is a dictionary
1779 like posix.environ. */
1780
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001781 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001782 return NULL;
1783 if (PyList_Check(argv)) {
1784 argc = PyList_Size(argv);
1785 getitem = PyList_GetItem;
1786 }
1787 else if (PyTuple_Check(argv)) {
1788 argc = PyTuple_Size(argv);
1789 getitem = PyTuple_GetItem;
1790 }
1791 else {
Fred Drake661ea262000-10-24 19:57:45 +00001792 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001793 return NULL;
1794 }
1795 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001796 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001797 return NULL;
1798 }
1799
1800 argvlist = PyMem_NEW(char *, argc+1);
1801 if (argvlist == NULL) {
1802 PyErr_NoMemory();
1803 return NULL;
1804 }
1805 for (i = 0; i < argc; i++) {
1806 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001807 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001808 &argvlist[i]))
1809 {
1810 goto fail_1;
1811 }
1812 }
1813 argvlist[argc] = NULL;
1814
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001815 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001816 envlist = PyMem_NEW(char *, i + 1);
1817 if (envlist == NULL) {
1818 PyErr_NoMemory();
1819 goto fail_1;
1820 }
1821 envc = 0;
1822 keys = PyMapping_Keys(env);
1823 vals = PyMapping_Values(env);
1824 if (!keys || !vals)
1825 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001826
Guido van Rossuma1065681999-01-25 23:20:23 +00001827 for (pos = 0; pos < i; pos++) {
1828 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001829 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001830
1831 key = PyList_GetItem(keys, pos);
1832 val = PyList_GetItem(vals, pos);
1833 if (!key || !val)
1834 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001835
Fred Drake661ea262000-10-24 19:57:45 +00001836 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1837 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001838 {
1839 goto fail_2;
1840 }
Tim Petersc8996f52001-12-03 20:41:00 +00001841 len = PyString_Size(key) + PyString_Size(val) + 2;
1842 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001843 if (p == NULL) {
1844 PyErr_NoMemory();
1845 goto fail_2;
1846 }
Tim Petersc8996f52001-12-03 20:41:00 +00001847 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001848 envlist[envc++] = p;
1849 }
1850 envlist[envc] = 0;
1851
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001852#if defined(PYOS_OS2) && defined(PYCC_GCC)
1853 Py_BEGIN_ALLOW_THREADS
1854 spawnval = spawnve(mode, path, argvlist, envlist);
1855 Py_END_ALLOW_THREADS
1856#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001857 if (mode == _OLD_P_OVERLAY)
1858 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001859
1860 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001861 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001862 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001863#endif
Tim Peters25059d32001-12-07 20:35:43 +00001864
Fred Drake699f3522000-06-29 21:12:41 +00001865 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001866 (void) posix_error();
1867 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001868#if SIZEOF_LONG == SIZEOF_VOID_P
1869 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001870#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001871 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001872#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001873
1874 fail_2:
1875 while (--envc >= 0)
1876 PyMem_DEL(envlist[envc]);
1877 PyMem_DEL(envlist);
1878 fail_1:
1879 PyMem_DEL(argvlist);
1880 Py_XDECREF(vals);
1881 Py_XDECREF(keys);
1882 return res;
1883}
1884#endif /* HAVE_SPAWNV */
1885
1886
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001887#ifdef HAVE_FORK1
1888static char posix_fork1__doc__[] =
1889"fork1() -> pid\n\
1890Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1891\n\
1892Return 0 to child process and PID of child to parent process.";
1893
1894static PyObject *
1895posix_fork1(self, args)
1896 PyObject *self;
1897 PyObject *args;
1898{
1899 int pid;
1900 if (!PyArg_ParseTuple(args, ":fork1"))
1901 return NULL;
1902 pid = fork1();
1903 if (pid == -1)
1904 return posix_error();
1905 PyOS_AfterFork();
1906 return PyInt_FromLong((long)pid);
1907}
1908#endif
1909
1910
Guido van Rossumad0ee831995-03-01 10:34:45 +00001911#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001912static char posix_fork__doc__[] =
1913"fork() -> pid\n\
1914Fork a child process.\n\
1915\n\
1916Return 0 to child process and PID of child to parent process.";
1917
Barry Warsaw53699e91996-12-10 23:23:01 +00001918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001919posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001920{
1921 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001922 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001923 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001924 pid = fork();
1925 if (pid == -1)
1926 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001927 if (pid == 0)
1928 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001929 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001930}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001931#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001932
Fred Drake8cef4cf2000-06-28 16:40:38 +00001933#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1934#ifdef HAVE_PTY_H
1935#include <pty.h>
1936#else
1937#ifdef HAVE_LIBUTIL_H
1938#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001939#endif /* HAVE_LIBUTIL_H */
1940#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001941#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001942
Thomas Wouters70c21a12000-07-14 14:28:33 +00001943#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001944static char posix_openpty__doc__[] =
1945"openpty() -> (master_fd, slave_fd)\n\
1946Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1947
1948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001949posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001950{
1951 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001952#ifndef HAVE_OPENPTY
1953 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001954#endif
1955
Fred Drake8cef4cf2000-06-28 16:40:38 +00001956 if (!PyArg_ParseTuple(args, ":openpty"))
1957 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001958
1959#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001960 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1961 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001962#else
1963 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1964 if (slave_name == NULL)
1965 return posix_error();
1966
1967 slave_fd = open(slave_name, O_RDWR);
1968 if (slave_fd < 0)
1969 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001970#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001971
Fred Drake8cef4cf2000-06-28 16:40:38 +00001972 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001973
Fred Drake8cef4cf2000-06-28 16:40:38 +00001974}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001975#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001976
1977#ifdef HAVE_FORKPTY
1978static char posix_forkpty__doc__[] =
1979"forkpty() -> (pid, master_fd)\n\
1980Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1981Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1982To both, return fd of newly opened pseudo-terminal.\n";
1983
1984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001985posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001986{
1987 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00001988
Fred Drake8cef4cf2000-06-28 16:40:38 +00001989 if (!PyArg_ParseTuple(args, ":forkpty"))
1990 return NULL;
1991 pid = forkpty(&master_fd, NULL, NULL, NULL);
1992 if (pid == -1)
1993 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001994 if (pid == 0)
1995 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001996 return Py_BuildValue("(ii)", pid, master_fd);
1997}
1998#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001999
Guido van Rossumad0ee831995-03-01 10:34:45 +00002000#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002001static char posix_getegid__doc__[] =
2002"getegid() -> egid\n\
2003Return the current process's effective group id.";
2004
Barry Warsaw53699e91996-12-10 23:23:01 +00002005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002006posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002007{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002008 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002009 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002010 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002011}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002012#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Guido van Rossumad0ee831995-03-01 10:34:45 +00002015#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002016static char posix_geteuid__doc__[] =
2017"geteuid() -> euid\n\
2018Return the current process's effective user id.";
2019
Barry Warsaw53699e91996-12-10 23:23:01 +00002020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002021posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002022{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002023 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002024 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002025 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002026}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002027#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002029
Guido van Rossumad0ee831995-03-01 10:34:45 +00002030#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002031static char posix_getgid__doc__[] =
2032"getgid() -> gid\n\
2033Return the current process's group id.";
2034
Barry Warsaw53699e91996-12-10 23:23:01 +00002035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002036posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002037{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002038 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002039 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002040 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002041}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002042#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002044
2045static char posix_getpid__doc__[] =
2046"getpid() -> pid\n\
2047Return the current process id";
2048
Barry Warsaw53699e91996-12-10 23:23:01 +00002049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002050posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002051{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002052 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002053 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002054 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002055}
2056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002057
Fred Drakec9680921999-12-13 16:37:25 +00002058#ifdef HAVE_GETGROUPS
2059static char posix_getgroups__doc__[] = "\
2060getgroups() -> list of group IDs\n\
2061Return list of supplemental group IDs for the process.";
2062
2063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002064posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002065{
2066 PyObject *result = NULL;
2067
2068 if (PyArg_ParseTuple(args, ":getgroups")) {
2069#ifdef NGROUPS_MAX
2070#define MAX_GROUPS NGROUPS_MAX
2071#else
2072 /* defined to be 16 on Solaris7, so this should be a small number */
2073#define MAX_GROUPS 64
2074#endif
2075 gid_t grouplist[MAX_GROUPS];
2076 int n;
2077
2078 n = getgroups(MAX_GROUPS, grouplist);
2079 if (n < 0)
2080 posix_error();
2081 else {
2082 result = PyList_New(n);
2083 if (result != NULL) {
2084 PyObject *o;
2085 int i;
2086 for (i = 0; i < n; ++i) {
2087 o = PyInt_FromLong((long)grouplist[i]);
2088 if (o == NULL) {
2089 Py_DECREF(result);
2090 result = NULL;
2091 break;
2092 }
2093 PyList_SET_ITEM(result, i, o);
2094 }
2095 }
2096 }
2097 }
2098 return result;
2099}
2100#endif
2101
Guido van Rossumb6775db1994-08-01 11:34:53 +00002102#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002103static char posix_getpgrp__doc__[] =
2104"getpgrp() -> pgrp\n\
2105Return the current process group id.";
2106
Barry Warsaw53699e91996-12-10 23:23:01 +00002107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002108posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002109{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002110 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002111 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002112#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002113 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002114#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002115 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002116#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002117}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002118#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002120
Guido van Rossumb6775db1994-08-01 11:34:53 +00002121#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122static char posix_setpgrp__doc__[] =
2123"setpgrp() -> None\n\
2124Make this process a session leader.";
2125
Barry Warsaw53699e91996-12-10 23:23:01 +00002126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002127posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002128{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002129 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002130 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002131#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002132 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002133#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002134 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002135#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002136 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002137 Py_INCREF(Py_None);
2138 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002139}
2140
Guido van Rossumb6775db1994-08-01 11:34:53 +00002141#endif /* HAVE_SETPGRP */
2142
Guido van Rossumad0ee831995-03-01 10:34:45 +00002143#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002144static char posix_getppid__doc__[] =
2145"getppid() -> ppid\n\
2146Return the parent's process id.";
2147
Barry Warsaw53699e91996-12-10 23:23:01 +00002148static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002149posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002150{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002151 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002152 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002153 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002154}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002155#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002156
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002157
Fred Drake12c6e2d1999-12-14 21:25:03 +00002158#ifdef HAVE_GETLOGIN
2159static char posix_getlogin__doc__[] = "\
2160getlogin() -> string\n\
2161Return the actual login name.";
2162
2163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002164posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002165{
2166 PyObject *result = NULL;
2167
2168 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002169 char *name;
2170 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002171
Fred Drakea30680b2000-12-06 21:24:28 +00002172 errno = 0;
2173 name = getlogin();
2174 if (name == NULL) {
2175 if (errno)
2176 posix_error();
2177 else
2178 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002179 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002180 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002181 else
2182 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002183 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002184 }
2185 return result;
2186}
2187#endif
2188
Guido van Rossumad0ee831995-03-01 10:34:45 +00002189#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002190static char posix_getuid__doc__[] =
2191"getuid() -> uid\n\
2192Return the current process's user id.";
2193
Barry Warsaw53699e91996-12-10 23:23:01 +00002194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002195posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002196{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002197 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002198 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002199 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002200}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002201#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002203
Guido van Rossumad0ee831995-03-01 10:34:45 +00002204#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002205static char posix_kill__doc__[] =
2206"kill(pid, sig) -> None\n\
2207Kill a process with a signal.";
2208
Barry Warsaw53699e91996-12-10 23:23:01 +00002209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002210posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002211{
2212 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002213 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002214 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002215#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002216 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2217 APIRET rc;
2218 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002219 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002220
2221 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2222 APIRET rc;
2223 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002224 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002225
2226 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002227 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002228#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002229 if (kill(pid, sig) == -1)
2230 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002231#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002232 Py_INCREF(Py_None);
2233 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002234}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002235#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002236
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002237#ifdef HAVE_KILLPG
2238static char posix_killpg__doc__[] =
2239"killpg(pgid, sig) -> None\n\
2240Kill a process group with a signal.";
2241
2242static PyObject *
2243posix_killpg(PyObject *self, PyObject *args)
2244{
2245 int pgid, sig;
2246 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2247 return NULL;
2248 if (killpg(pgid, sig) == -1)
2249 return posix_error();
2250 Py_INCREF(Py_None);
2251 return Py_None;
2252}
2253#endif
2254
Guido van Rossumc0125471996-06-28 18:55:32 +00002255#ifdef HAVE_PLOCK
2256
2257#ifdef HAVE_SYS_LOCK_H
2258#include <sys/lock.h>
2259#endif
2260
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002261static char posix_plock__doc__[] =
2262"plock(op) -> None\n\
2263Lock program segments into memory.";
2264
Barry Warsaw53699e91996-12-10 23:23:01 +00002265static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002266posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002267{
2268 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002269 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002270 return NULL;
2271 if (plock(op) == -1)
2272 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002273 Py_INCREF(Py_None);
2274 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002275}
2276#endif
2277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002278
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002279#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002280static char posix_popen__doc__[] =
2281"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2282Open a pipe to/from a command returning a file object.";
2283
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002284#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002285#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002286static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002287async_system(const char *command)
2288{
2289 char *p, errormsg[256], args[1024];
2290 RESULTCODES rcodes;
2291 APIRET rc;
2292 char *shell = getenv("COMSPEC");
2293 if (!shell)
2294 shell = "cmd";
2295
2296 strcpy(args, shell);
2297 p = &args[ strlen(args)+1 ];
2298 strcpy(p, "/c ");
2299 strcat(p, command);
2300 p += strlen(p) + 1;
2301 *p = '\0';
2302
2303 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002304 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002305 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002306 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002307 &rcodes, shell);
2308 return rc;
2309}
2310
Guido van Rossumd48f2521997-12-05 22:19:34 +00002311static FILE *
2312popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002313{
2314 HFILE rhan, whan;
2315 FILE *retfd = NULL;
2316 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2317
Guido van Rossumd48f2521997-12-05 22:19:34 +00002318 if (rc != NO_ERROR) {
2319 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002320 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002321 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002322
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002323 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2324 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002325
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002326 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2327 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002328
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002329 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2330 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002331
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002332 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002333 }
2334
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002335 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2336 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002338 if (rc == NO_ERROR)
2339 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2340
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002341 close(oldfd); /* And Close Saved STDOUT Handle */
2342 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002343
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002344 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2345 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002346
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002347 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2348 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002349
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002350 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2351 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002352
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002353 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002354 }
2355
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002356 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2357 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002358
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002359 if (rc == NO_ERROR)
2360 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2361
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002362 close(oldfd); /* And Close Saved STDIN Handle */
2363 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002364
Guido van Rossumd48f2521997-12-05 22:19:34 +00002365 } else {
2366 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002367 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002368 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002369}
2370
2371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002372posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002373{
2374 char *name;
2375 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002376 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002377 FILE *fp;
2378 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002379 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002380 return NULL;
2381 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002382 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002383 Py_END_ALLOW_THREADS
2384 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002385 return os2_error(err);
2386
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002387 f = PyFile_FromFile(fp, name, mode, fclose);
2388 if (f != NULL)
2389 PyFile_SetBufSize(f, bufsize);
2390 return f;
2391}
2392
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002393#elif defined(PYCC_GCC)
2394
2395/* standard posix version of popen() support */
2396static PyObject *
2397posix_popen(PyObject *self, PyObject *args)
2398{
2399 char *name;
2400 char *mode = "r";
2401 int bufsize = -1;
2402 FILE *fp;
2403 PyObject *f;
2404 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2405 return NULL;
2406 Py_BEGIN_ALLOW_THREADS
2407 fp = popen(name, mode);
2408 Py_END_ALLOW_THREADS
2409 if (fp == NULL)
2410 return posix_error();
2411 f = PyFile_FromFile(fp, name, mode, pclose);
2412 if (f != NULL)
2413 PyFile_SetBufSize(f, bufsize);
2414 return f;
2415}
2416
2417/* fork() under OS/2 has lots'o'warts
2418 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2419 * most of this code is a ripoff of the win32 code, but using the
2420 * capabilities of EMX's C library routines
2421 */
2422
2423/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2424#define POPEN_1 1
2425#define POPEN_2 2
2426#define POPEN_3 3
2427#define POPEN_4 4
2428
2429static PyObject *_PyPopen(char *, int, int, int);
2430static int _PyPclose(FILE *file);
2431
2432/*
2433 * Internal dictionary mapping popen* file pointers to process handles,
2434 * for use when retrieving the process exit code. See _PyPclose() below
2435 * for more information on this dictionary's use.
2436 */
2437static PyObject *_PyPopenProcs = NULL;
2438
2439/* os2emx version of popen2()
2440 *
2441 * The result of this function is a pipe (file) connected to the
2442 * process's stdin, and a pipe connected to the process's stdout.
2443 */
2444
2445static PyObject *
2446os2emx_popen2(PyObject *self, PyObject *args)
2447{
2448 PyObject *f;
2449 int tm=0;
2450
2451 char *cmdstring;
2452 char *mode = "t";
2453 int bufsize = -1;
2454 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2455 return NULL;
2456
2457 if (*mode == 't')
2458 tm = O_TEXT;
2459 else if (*mode != 'b') {
2460 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2461 return NULL;
2462 } else
2463 tm = O_BINARY;
2464
2465 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2466
2467 return f;
2468}
2469
2470/*
2471 * Variation on os2emx.popen2
2472 *
2473 * The result of this function is 3 pipes - the process's stdin,
2474 * stdout and stderr
2475 */
2476
2477static PyObject *
2478os2emx_popen3(PyObject *self, PyObject *args)
2479{
2480 PyObject *f;
2481 int tm = 0;
2482
2483 char *cmdstring;
2484 char *mode = "t";
2485 int bufsize = -1;
2486 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2487 return NULL;
2488
2489 if (*mode == 't')
2490 tm = O_TEXT;
2491 else if (*mode != 'b') {
2492 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2493 return NULL;
2494 } else
2495 tm = O_BINARY;
2496
2497 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2498
2499 return f;
2500}
2501
2502/*
2503 * Variation on os2emx.popen2
2504 *
2505 * The result of this function is 2 pipes - the processes stdin,
2506 * and stdout+stderr combined as a single pipe.
2507 */
2508
2509static PyObject *
2510os2emx_popen4(PyObject *self, PyObject *args)
2511{
2512 PyObject *f;
2513 int tm = 0;
2514
2515 char *cmdstring;
2516 char *mode = "t";
2517 int bufsize = -1;
2518 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2519 return NULL;
2520
2521 if (*mode == 't')
2522 tm = O_TEXT;
2523 else if (*mode != 'b') {
2524 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2525 return NULL;
2526 } else
2527 tm = O_BINARY;
2528
2529 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2530
2531 return f;
2532}
2533
2534/* a couple of structures for convenient handling of multiple
2535 * file handles and pipes
2536 */
2537struct file_ref
2538{
2539 int handle;
2540 int flags;
2541};
2542
2543struct pipe_ref
2544{
2545 int rd;
2546 int wr;
2547};
2548
2549/* The following code is derived from the win32 code */
2550
2551static PyObject *
2552_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2553{
2554 struct file_ref stdio[3];
2555 struct pipe_ref p_fd[3];
2556 FILE *p_s[3];
2557 int file_count, i, pipe_err, pipe_pid;
2558 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2559 PyObject *f, *p_f[3];
2560
2561 /* file modes for subsequent fdopen's on pipe handles */
2562 if (mode == O_TEXT)
2563 {
2564 rd_mode = "rt";
2565 wr_mode = "wt";
2566 }
2567 else
2568 {
2569 rd_mode = "rb";
2570 wr_mode = "wb";
2571 }
2572
2573 /* prepare shell references */
2574 if ((shell = getenv("EMXSHELL")) == NULL)
2575 if ((shell = getenv("COMSPEC")) == NULL)
2576 {
2577 errno = ENOENT;
2578 return posix_error();
2579 }
2580
2581 sh_name = _getname(shell);
2582 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2583 opt = "/c";
2584 else
2585 opt = "-c";
2586
2587 /* save current stdio fds + their flags, and set not inheritable */
2588 i = pipe_err = 0;
2589 while (pipe_err >= 0 && i < 3)
2590 {
2591 pipe_err = stdio[i].handle = dup(i);
2592 stdio[i].flags = fcntl(i, F_GETFD, 0);
2593 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2594 i++;
2595 }
2596 if (pipe_err < 0)
2597 {
2598 /* didn't get them all saved - clean up and bail out */
2599 int saved_err = errno;
2600 while (i-- > 0)
2601 {
2602 close(stdio[i].handle);
2603 }
2604 errno = saved_err;
2605 return posix_error();
2606 }
2607
2608 /* create pipe ends */
2609 file_count = 2;
2610 if (n == POPEN_3)
2611 file_count = 3;
2612 i = pipe_err = 0;
2613 while ((pipe_err == 0) && (i < file_count))
2614 pipe_err = pipe((int *)&p_fd[i++]);
2615 if (pipe_err < 0)
2616 {
2617 /* didn't get them all made - clean up and bail out */
2618 while (i-- > 0)
2619 {
2620 close(p_fd[i].wr);
2621 close(p_fd[i].rd);
2622 }
2623 errno = EPIPE;
2624 return posix_error();
2625 }
2626
2627 /* change the actual standard IO streams over temporarily,
2628 * making the retained pipe ends non-inheritable
2629 */
2630 pipe_err = 0;
2631
2632 /* - stdin */
2633 if (dup2(p_fd[0].rd, 0) == 0)
2634 {
2635 close(p_fd[0].rd);
2636 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2637 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2638 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2639 {
2640 close(p_fd[0].wr);
2641 pipe_err = -1;
2642 }
2643 }
2644 else
2645 {
2646 pipe_err = -1;
2647 }
2648
2649 /* - stdout */
2650 if (pipe_err == 0)
2651 {
2652 if (dup2(p_fd[1].wr, 1) == 1)
2653 {
2654 close(p_fd[1].wr);
2655 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2656 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2657 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2658 {
2659 close(p_fd[1].rd);
2660 pipe_err = -1;
2661 }
2662 }
2663 else
2664 {
2665 pipe_err = -1;
2666 }
2667 }
2668
2669 /* - stderr, as required */
2670 if (pipe_err == 0)
2671 switch (n)
2672 {
2673 case POPEN_3:
2674 {
2675 if (dup2(p_fd[2].wr, 2) == 2)
2676 {
2677 close(p_fd[2].wr);
2678 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2679 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2680 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2681 {
2682 close(p_fd[2].rd);
2683 pipe_err = -1;
2684 }
2685 }
2686 else
2687 {
2688 pipe_err = -1;
2689 }
2690 break;
2691 }
2692
2693 case POPEN_4:
2694 {
2695 if (dup2(1, 2) != 2)
2696 {
2697 pipe_err = -1;
2698 }
2699 break;
2700 }
2701 }
2702
2703 /* spawn the child process */
2704 if (pipe_err == 0)
2705 {
2706 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2707 if (pipe_pid == -1)
2708 {
2709 pipe_err = -1;
2710 }
2711 else
2712 {
2713 /* save the PID into the FILE structure
2714 * NOTE: this implementation doesn't actually
2715 * take advantage of this, but do it for
2716 * completeness - AIM Apr01
2717 */
2718 for (i = 0; i < file_count; i++)
2719 p_s[i]->_pid = pipe_pid;
2720 }
2721 }
2722
2723 /* reset standard IO to normal */
2724 for (i = 0; i < 3; i++)
2725 {
2726 dup2(stdio[i].handle, i);
2727 fcntl(i, F_SETFD, stdio[i].flags);
2728 close(stdio[i].handle);
2729 }
2730
2731 /* if any remnant problems, clean up and bail out */
2732 if (pipe_err < 0)
2733 {
2734 for (i = 0; i < 3; i++)
2735 {
2736 close(p_fd[i].rd);
2737 close(p_fd[i].wr);
2738 }
2739 errno = EPIPE;
2740 return posix_error_with_filename(cmdstring);
2741 }
2742
2743 /* build tuple of file objects to return */
2744 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2745 PyFile_SetBufSize(p_f[0], bufsize);
2746 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2747 PyFile_SetBufSize(p_f[1], bufsize);
2748 if (n == POPEN_3)
2749 {
2750 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2751 PyFile_SetBufSize(p_f[0], bufsize);
2752 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2753 }
2754 else
2755 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2756
2757 /*
2758 * Insert the files we've created into the process dictionary
2759 * all referencing the list with the process handle and the
2760 * initial number of files (see description below in _PyPclose).
2761 * Since if _PyPclose later tried to wait on a process when all
2762 * handles weren't closed, it could create a deadlock with the
2763 * child, we spend some energy here to try to ensure that we
2764 * either insert all file handles into the dictionary or none
2765 * at all. It's a little clumsy with the various popen modes
2766 * and variable number of files involved.
2767 */
2768 if (!_PyPopenProcs)
2769 {
2770 _PyPopenProcs = PyDict_New();
2771 }
2772
2773 if (_PyPopenProcs)
2774 {
2775 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2776 int ins_rc[3];
2777
2778 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2779 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2780
2781 procObj = PyList_New(2);
2782 pidObj = PyInt_FromLong((long) pipe_pid);
2783 intObj = PyInt_FromLong((long) file_count);
2784
2785 if (procObj && pidObj && intObj)
2786 {
2787 PyList_SetItem(procObj, 0, pidObj);
2788 PyList_SetItem(procObj, 1, intObj);
2789
2790 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2791 if (fileObj[0])
2792 {
2793 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2794 fileObj[0],
2795 procObj);
2796 }
2797 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2798 if (fileObj[1])
2799 {
2800 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2801 fileObj[1],
2802 procObj);
2803 }
2804 if (file_count >= 3)
2805 {
2806 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2807 if (fileObj[2])
2808 {
2809 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2810 fileObj[2],
2811 procObj);
2812 }
2813 }
2814
2815 if (ins_rc[0] < 0 || !fileObj[0] ||
2816 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2817 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2818 {
2819 /* Something failed - remove any dictionary
2820 * entries that did make it.
2821 */
2822 if (!ins_rc[0] && fileObj[0])
2823 {
2824 PyDict_DelItem(_PyPopenProcs,
2825 fileObj[0]);
2826 }
2827 if (!ins_rc[1] && fileObj[1])
2828 {
2829 PyDict_DelItem(_PyPopenProcs,
2830 fileObj[1]);
2831 }
2832 if (!ins_rc[2] && fileObj[2])
2833 {
2834 PyDict_DelItem(_PyPopenProcs,
2835 fileObj[2]);
2836 }
2837 }
2838 }
2839
2840 /*
2841 * Clean up our localized references for the dictionary keys
2842 * and value since PyDict_SetItem will Py_INCREF any copies
2843 * that got placed in the dictionary.
2844 */
2845 Py_XDECREF(procObj);
2846 Py_XDECREF(fileObj[0]);
2847 Py_XDECREF(fileObj[1]);
2848 Py_XDECREF(fileObj[2]);
2849 }
2850
2851 /* Child is launched. */
2852 return f;
2853}
2854
2855/*
2856 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2857 * exit code for the child process and return as a result of the close.
2858 *
2859 * This function uses the _PyPopenProcs dictionary in order to map the
2860 * input file pointer to information about the process that was
2861 * originally created by the popen* call that created the file pointer.
2862 * The dictionary uses the file pointer as a key (with one entry
2863 * inserted for each file returned by the original popen* call) and a
2864 * single list object as the value for all files from a single call.
2865 * The list object contains the Win32 process handle at [0], and a file
2866 * count at [1], which is initialized to the total number of file
2867 * handles using that list.
2868 *
2869 * This function closes whichever handle it is passed, and decrements
2870 * the file count in the dictionary for the process handle pointed to
2871 * by this file. On the last close (when the file count reaches zero),
2872 * this function will wait for the child process and then return its
2873 * exit code as the result of the close() operation. This permits the
2874 * files to be closed in any order - it is always the close() of the
2875 * final handle that will return the exit code.
2876 */
2877
2878 /* RED_FLAG 31-Aug-2000 Tim
2879 * This is always called (today!) between a pair of
2880 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2881 * macros. So the thread running this has no valid thread state, as
2882 * far as Python is concerned. However, this calls some Python API
2883 * functions that cannot be called safely without a valid thread
2884 * state, in particular PyDict_GetItem.
2885 * As a temporary hack (although it may last for years ...), we
2886 * *rely* on not having a valid thread state in this function, in
2887 * order to create our own "from scratch".
2888 * This will deadlock if _PyPclose is ever called by a thread
2889 * holding the global lock.
2890 * (The OS/2 EMX thread support appears to cover the case where the
2891 * lock is already held - AIM Apr01)
2892 */
2893
2894static int _PyPclose(FILE *file)
2895{
2896 int result;
2897 int exit_code;
2898 int pipe_pid;
2899 PyObject *procObj, *pidObj, *intObj, *fileObj;
2900 int file_count;
2901#ifdef WITH_THREAD
2902 PyInterpreterState* pInterpreterState;
2903 PyThreadState* pThreadState;
2904#endif
2905
2906 /* Close the file handle first, to ensure it can't block the
2907 * child from exiting if it's the last handle.
2908 */
2909 result = fclose(file);
2910
2911#ifdef WITH_THREAD
2912 /* Bootstrap a valid thread state into existence. */
2913 pInterpreterState = PyInterpreterState_New();
2914 if (!pInterpreterState) {
2915 /* Well, we're hosed now! We don't have a thread
2916 * state, so can't call a nice error routine, or raise
2917 * an exception. Just die.
2918 */
2919 Py_FatalError("unable to allocate interpreter state "
2920 "when closing popen object.");
2921 return -1; /* unreachable */
2922 }
2923 pThreadState = PyThreadState_New(pInterpreterState);
2924 if (!pThreadState) {
2925 Py_FatalError("unable to allocate thread state "
2926 "when closing popen object.");
2927 return -1; /* unreachable */
2928 }
2929 /* Grab the global lock. Note that this will deadlock if the
2930 * current thread already has the lock! (see RED_FLAG comments
2931 * before this function)
2932 */
2933 PyEval_RestoreThread(pThreadState);
2934#endif
2935
2936 if (_PyPopenProcs)
2937 {
2938 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2939 (procObj = PyDict_GetItem(_PyPopenProcs,
2940 fileObj)) != NULL &&
2941 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2942 (intObj = PyList_GetItem(procObj,1)) != NULL)
2943 {
2944 pipe_pid = (int) PyInt_AsLong(pidObj);
2945 file_count = (int) PyInt_AsLong(intObj);
2946
2947 if (file_count > 1)
2948 {
2949 /* Still other files referencing process */
2950 file_count--;
2951 PyList_SetItem(procObj,1,
2952 PyInt_FromLong((long) file_count));
2953 }
2954 else
2955 {
2956 /* Last file for this process */
2957 if (result != EOF &&
2958 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2959 {
2960 /* extract exit status */
2961 if (WIFEXITED(exit_code))
2962 {
2963 result = WEXITSTATUS(exit_code);
2964 }
2965 else
2966 {
2967 errno = EPIPE;
2968 result = -1;
2969 }
2970 }
2971 else
2972 {
2973 /* Indicate failure - this will cause the file object
2974 * to raise an I/O error and translate the last
2975 * error code from errno. We do have a problem with
2976 * last errors that overlap the normal errno table,
2977 * but that's a consistent problem with the file object.
2978 */
2979 result = -1;
2980 }
2981 }
2982
2983 /* Remove this file pointer from dictionary */
2984 PyDict_DelItem(_PyPopenProcs, fileObj);
2985
2986 if (PyDict_Size(_PyPopenProcs) == 0)
2987 {
2988 Py_DECREF(_PyPopenProcs);
2989 _PyPopenProcs = NULL;
2990 }
2991
2992 } /* if object retrieval ok */
2993
2994 Py_XDECREF(fileObj);
2995 } /* if _PyPopenProcs */
2996
2997#ifdef WITH_THREAD
2998 /* Tear down the thread & interpreter states.
2999 * Note that interpreter state clear & delete functions automatically
3000 * call the thread clear & delete functions, and indeed insist on
3001 * doing that themselves. The lock must be held during the clear, but
3002 * need not be held during the delete.
3003 */
3004 PyInterpreterState_Clear(pInterpreterState);
3005 PyEval_ReleaseThread(pThreadState);
3006 PyInterpreterState_Delete(pInterpreterState);
3007#endif
3008
3009 return result;
3010}
3011
3012#endif /* PYCC_??? */
3013
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003014#elif defined(MS_WIN32)
3015
3016/*
3017 * Portable 'popen' replacement for Win32.
3018 *
3019 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3020 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003021 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003022 */
3023
3024#include <malloc.h>
3025#include <io.h>
3026#include <fcntl.h>
3027
3028/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3029#define POPEN_1 1
3030#define POPEN_2 2
3031#define POPEN_3 3
3032#define POPEN_4 4
3033
3034static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003035static int _PyPclose(FILE *file);
3036
3037/*
3038 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003039 * for use when retrieving the process exit code. See _PyPclose() below
3040 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003041 */
3042static PyObject *_PyPopenProcs = NULL;
3043
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003044
3045/* popen that works from a GUI.
3046 *
3047 * The result of this function is a pipe (file) connected to the
3048 * processes stdin or stdout, depending on the requested mode.
3049 */
3050
3051static PyObject *
3052posix_popen(PyObject *self, PyObject *args)
3053{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003054 PyObject *f, *s;
3055 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003056
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003057 char *cmdstring;
3058 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003059 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003060 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003061 return NULL;
3062
3063 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003064
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003065 if (*mode == 'r')
3066 tm = _O_RDONLY;
3067 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003068 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003069 return NULL;
3070 } else
3071 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003072
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003073 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003074 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003075 return NULL;
3076 }
3077
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003078 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003079 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003080 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003081 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003082 else
3083 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3084
3085 return f;
3086}
3087
3088/* Variation on win32pipe.popen
3089 *
3090 * The result of this function is a pipe (file) connected to the
3091 * process's stdin, and a pipe connected to the process's stdout.
3092 */
3093
3094static PyObject *
3095win32_popen2(PyObject *self, PyObject *args)
3096{
3097 PyObject *f;
3098 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003099
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003100 char *cmdstring;
3101 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003102 int bufsize = -1;
3103 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003104 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003105
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003106 if (*mode == 't')
3107 tm = _O_TEXT;
3108 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003109 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003110 return NULL;
3111 } else
3112 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003113
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003114 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003115 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003116 return NULL;
3117 }
3118
3119 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003120
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003121 return f;
3122}
3123
3124/*
3125 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003126 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003127 * The result of this function is 3 pipes - the process's stdin,
3128 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003129 */
3130
3131static PyObject *
3132win32_popen3(PyObject *self, PyObject *args)
3133{
3134 PyObject *f;
3135 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003136
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003137 char *cmdstring;
3138 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003139 int bufsize = -1;
3140 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003141 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003142
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003143 if (*mode == 't')
3144 tm = _O_TEXT;
3145 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003146 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003147 return NULL;
3148 } else
3149 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003150
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003151 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003152 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003153 return NULL;
3154 }
3155
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003156 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003157
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003158 return f;
3159}
3160
3161/*
3162 * Variation on win32pipe.popen
3163 *
Tim Peters5aa91602002-01-30 05:46:57 +00003164 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003165 * and stdout+stderr combined as a single pipe.
3166 */
3167
3168static PyObject *
3169win32_popen4(PyObject *self, PyObject *args)
3170{
3171 PyObject *f;
3172 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003173
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003174 char *cmdstring;
3175 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003176 int bufsize = -1;
3177 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003178 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003179
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003180 if (*mode == 't')
3181 tm = _O_TEXT;
3182 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003183 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003184 return NULL;
3185 } else
3186 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003187
3188 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003189 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003190 return NULL;
3191 }
3192
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003193 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003194
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003195 return f;
3196}
3197
Mark Hammond08501372001-01-31 07:30:29 +00003198static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003199_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003200 HANDLE hStdin,
3201 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003202 HANDLE hStderr,
3203 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003204{
3205 PROCESS_INFORMATION piProcInfo;
3206 STARTUPINFO siStartInfo;
3207 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003208 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003209 int i;
3210 int x;
3211
3212 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003213 char *comshell;
3214
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003215 s1 = (char *)_alloca(i);
3216 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3217 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003218
3219 /* Explicitly check if we are using COMMAND.COM. If we are
3220 * then use the w9xpopen hack.
3221 */
3222 comshell = s1 + x;
3223 while (comshell >= s1 && *comshell != '\\')
3224 --comshell;
3225 ++comshell;
3226
3227 if (GetVersion() < 0x80000000 &&
3228 _stricmp(comshell, "command.com") != 0) {
3229 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003230 x = i + strlen(s3) + strlen(cmdstring) + 1;
3231 s2 = (char *)_alloca(x);
3232 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003233 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003234 }
3235 else {
3236 /*
Tim Peters402d5982001-08-27 06:37:48 +00003237 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3238 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003239 */
Mark Hammond08501372001-01-31 07:30:29 +00003240 char modulepath[_MAX_PATH];
3241 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003242 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3243 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003244 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003245 x = i+1;
3246 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003247 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003248 strncat(modulepath,
3249 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003250 (sizeof(modulepath)/sizeof(modulepath[0]))
3251 -strlen(modulepath));
3252 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003253 /* Eeek - file-not-found - possibly an embedding
3254 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003255 */
Tim Peters5aa91602002-01-30 05:46:57 +00003256 strncpy(modulepath,
3257 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003258 sizeof(modulepath)/sizeof(modulepath[0]));
3259 if (modulepath[strlen(modulepath)-1] != '\\')
3260 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003261 strncat(modulepath,
3262 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003263 (sizeof(modulepath)/sizeof(modulepath[0]))
3264 -strlen(modulepath));
3265 /* No where else to look - raise an easily identifiable
3266 error, rather than leaving Windows to report
3267 "file not found" - as the user is probably blissfully
3268 unaware this shim EXE is used, and it will confuse them.
3269 (well, it confused me for a while ;-)
3270 */
3271 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003272 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003273 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003274 "for popen to work with your shell "
3275 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003276 szConsoleSpawn);
3277 return FALSE;
3278 }
3279 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003280 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003281 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003282 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003283
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003284 s2 = (char *)_alloca(x);
3285 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003286 PyOS_snprintf(
3287 s2, x,
Mark Hammond08501372001-01-31 07:30:29 +00003288 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003289 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003290 s1,
3291 s3,
3292 cmdstring);
3293 }
3294 }
3295
3296 /* Could be an else here to try cmd.exe / command.com in the path
3297 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003298 else {
Tim Peters402d5982001-08-27 06:37:48 +00003299 PyErr_SetString(PyExc_RuntimeError,
3300 "Cannot locate a COMSPEC environment variable to "
3301 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003302 return FALSE;
3303 }
Tim Peters5aa91602002-01-30 05:46:57 +00003304
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003305 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3306 siStartInfo.cb = sizeof(STARTUPINFO);
3307 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3308 siStartInfo.hStdInput = hStdin;
3309 siStartInfo.hStdOutput = hStdout;
3310 siStartInfo.hStdError = hStderr;
3311 siStartInfo.wShowWindow = SW_HIDE;
3312
3313 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003314 s2,
3315 NULL,
3316 NULL,
3317 TRUE,
3318 CREATE_NEW_CONSOLE,
3319 NULL,
3320 NULL,
3321 &siStartInfo,
3322 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003323 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003324 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003325
Mark Hammondb37a3732000-08-14 04:47:33 +00003326 /* Return process handle */
3327 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003328 return TRUE;
3329 }
Tim Peters402d5982001-08-27 06:37:48 +00003330 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003331 return FALSE;
3332}
3333
3334/* The following code is based off of KB: Q190351 */
3335
3336static PyObject *
3337_PyPopen(char *cmdstring, int mode, int n)
3338{
3339 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3340 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003341 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003342
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003343 SECURITY_ATTRIBUTES saAttr;
3344 BOOL fSuccess;
3345 int fd1, fd2, fd3;
3346 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003347 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003348 PyObject *f;
3349
3350 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3351 saAttr.bInheritHandle = TRUE;
3352 saAttr.lpSecurityDescriptor = NULL;
3353
3354 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3355 return win32_error("CreatePipe", NULL);
3356
3357 /* Create new output read handle and the input write handle. Set
3358 * the inheritance properties to FALSE. Otherwise, the child inherits
3359 * the these handles; resulting in non-closeable handles to the pipes
3360 * being created. */
3361 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003362 GetCurrentProcess(), &hChildStdinWrDup, 0,
3363 FALSE,
3364 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003365 if (!fSuccess)
3366 return win32_error("DuplicateHandle", NULL);
3367
3368 /* Close the inheritable version of ChildStdin
3369 that we're using. */
3370 CloseHandle(hChildStdinWr);
3371
3372 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3373 return win32_error("CreatePipe", NULL);
3374
3375 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003376 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3377 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003378 if (!fSuccess)
3379 return win32_error("DuplicateHandle", NULL);
3380
3381 /* Close the inheritable version of ChildStdout
3382 that we're using. */
3383 CloseHandle(hChildStdoutRd);
3384
3385 if (n != POPEN_4) {
3386 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3387 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003388 fSuccess = DuplicateHandle(GetCurrentProcess(),
3389 hChildStderrRd,
3390 GetCurrentProcess(),
3391 &hChildStderrRdDup, 0,
3392 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003393 if (!fSuccess)
3394 return win32_error("DuplicateHandle", NULL);
3395 /* Close the inheritable version of ChildStdErr that we're using. */
3396 CloseHandle(hChildStderrRd);
3397 }
Tim Peters5aa91602002-01-30 05:46:57 +00003398
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003399 switch (n) {
3400 case POPEN_1:
3401 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3402 case _O_WRONLY | _O_TEXT:
3403 /* Case for writing to child Stdin in text mode. */
3404 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3405 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003406 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003407 PyFile_SetBufSize(f, 0);
3408 /* We don't care about these pipes anymore, so close them. */
3409 CloseHandle(hChildStdoutRdDup);
3410 CloseHandle(hChildStderrRdDup);
3411 break;
3412
3413 case _O_RDONLY | _O_TEXT:
3414 /* Case for reading from child Stdout in text mode. */
3415 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3416 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003417 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003418 PyFile_SetBufSize(f, 0);
3419 /* We don't care about these pipes anymore, so close them. */
3420 CloseHandle(hChildStdinWrDup);
3421 CloseHandle(hChildStderrRdDup);
3422 break;
3423
3424 case _O_RDONLY | _O_BINARY:
3425 /* Case for readinig from child Stdout in binary mode. */
3426 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3427 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003428 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003429 PyFile_SetBufSize(f, 0);
3430 /* We don't care about these pipes anymore, so close them. */
3431 CloseHandle(hChildStdinWrDup);
3432 CloseHandle(hChildStderrRdDup);
3433 break;
3434
3435 case _O_WRONLY | _O_BINARY:
3436 /* Case for writing to child Stdin in binary mode. */
3437 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3438 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003439 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003440 PyFile_SetBufSize(f, 0);
3441 /* We don't care about these pipes anymore, so close them. */
3442 CloseHandle(hChildStdoutRdDup);
3443 CloseHandle(hChildStderrRdDup);
3444 break;
3445 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003446 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003447 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003448
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003449 case POPEN_2:
3450 case POPEN_4:
3451 {
3452 char *m1, *m2;
3453 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003454
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003455 if (mode && _O_TEXT) {
3456 m1 = "r";
3457 m2 = "w";
3458 } else {
3459 m1 = "rb";
3460 m2 = "wb";
3461 }
3462
3463 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3464 f1 = _fdopen(fd1, m2);
3465 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3466 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003467 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003468 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003469 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003470 PyFile_SetBufSize(p2, 0);
3471
3472 if (n != 4)
3473 CloseHandle(hChildStderrRdDup);
3474
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003475 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003476 Py_XDECREF(p1);
3477 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003478 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003479 break;
3480 }
Tim Peters5aa91602002-01-30 05:46:57 +00003481
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003482 case POPEN_3:
3483 {
3484 char *m1, *m2;
3485 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003486
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003487 if (mode && _O_TEXT) {
3488 m1 = "r";
3489 m2 = "w";
3490 } else {
3491 m1 = "rb";
3492 m2 = "wb";
3493 }
3494
3495 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3496 f1 = _fdopen(fd1, m2);
3497 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3498 f2 = _fdopen(fd2, m1);
3499 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3500 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003501 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003502 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3503 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003504 PyFile_SetBufSize(p1, 0);
3505 PyFile_SetBufSize(p2, 0);
3506 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003507 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003508 Py_XDECREF(p1);
3509 Py_XDECREF(p2);
3510 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003511 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003512 break;
3513 }
3514 }
3515
3516 if (n == POPEN_4) {
3517 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003518 hChildStdinRd,
3519 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003520 hChildStdoutWr,
3521 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003522 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003523 }
3524 else {
3525 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003526 hChildStdinRd,
3527 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003528 hChildStderrWr,
3529 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003530 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003531 }
3532
Mark Hammondb37a3732000-08-14 04:47:33 +00003533 /*
3534 * Insert the files we've created into the process dictionary
3535 * all referencing the list with the process handle and the
3536 * initial number of files (see description below in _PyPclose).
3537 * Since if _PyPclose later tried to wait on a process when all
3538 * handles weren't closed, it could create a deadlock with the
3539 * child, we spend some energy here to try to ensure that we
3540 * either insert all file handles into the dictionary or none
3541 * at all. It's a little clumsy with the various popen modes
3542 * and variable number of files involved.
3543 */
3544 if (!_PyPopenProcs) {
3545 _PyPopenProcs = PyDict_New();
3546 }
3547
3548 if (_PyPopenProcs) {
3549 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3550 int ins_rc[3];
3551
3552 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3553 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3554
3555 procObj = PyList_New(2);
3556 hProcessObj = PyLong_FromVoidPtr(hProcess);
3557 intObj = PyInt_FromLong(file_count);
3558
3559 if (procObj && hProcessObj && intObj) {
3560 PyList_SetItem(procObj,0,hProcessObj);
3561 PyList_SetItem(procObj,1,intObj);
3562
3563 fileObj[0] = PyLong_FromVoidPtr(f1);
3564 if (fileObj[0]) {
3565 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3566 fileObj[0],
3567 procObj);
3568 }
3569 if (file_count >= 2) {
3570 fileObj[1] = PyLong_FromVoidPtr(f2);
3571 if (fileObj[1]) {
3572 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3573 fileObj[1],
3574 procObj);
3575 }
3576 }
3577 if (file_count >= 3) {
3578 fileObj[2] = PyLong_FromVoidPtr(f3);
3579 if (fileObj[2]) {
3580 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3581 fileObj[2],
3582 procObj);
3583 }
3584 }
3585
3586 if (ins_rc[0] < 0 || !fileObj[0] ||
3587 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3588 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3589 /* Something failed - remove any dictionary
3590 * entries that did make it.
3591 */
3592 if (!ins_rc[0] && fileObj[0]) {
3593 PyDict_DelItem(_PyPopenProcs,
3594 fileObj[0]);
3595 }
3596 if (!ins_rc[1] && fileObj[1]) {
3597 PyDict_DelItem(_PyPopenProcs,
3598 fileObj[1]);
3599 }
3600 if (!ins_rc[2] && fileObj[2]) {
3601 PyDict_DelItem(_PyPopenProcs,
3602 fileObj[2]);
3603 }
3604 }
3605 }
Tim Peters5aa91602002-01-30 05:46:57 +00003606
Mark Hammondb37a3732000-08-14 04:47:33 +00003607 /*
3608 * Clean up our localized references for the dictionary keys
3609 * and value since PyDict_SetItem will Py_INCREF any copies
3610 * that got placed in the dictionary.
3611 */
3612 Py_XDECREF(procObj);
3613 Py_XDECREF(fileObj[0]);
3614 Py_XDECREF(fileObj[1]);
3615 Py_XDECREF(fileObj[2]);
3616 }
3617
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003618 /* Child is launched. Close the parents copy of those pipe
3619 * handles that only the child should have open. You need to
3620 * make sure that no handles to the write end of the output pipe
3621 * are maintained in this process or else the pipe will not close
3622 * when the child process exits and the ReadFile will hang. */
3623
3624 if (!CloseHandle(hChildStdinRd))
3625 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003626
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003627 if (!CloseHandle(hChildStdoutWr))
3628 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003629
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003630 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3631 return win32_error("CloseHandle", NULL);
3632
3633 return f;
3634}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003635
3636/*
3637 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3638 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003639 *
3640 * This function uses the _PyPopenProcs dictionary in order to map the
3641 * input file pointer to information about the process that was
3642 * originally created by the popen* call that created the file pointer.
3643 * The dictionary uses the file pointer as a key (with one entry
3644 * inserted for each file returned by the original popen* call) and a
3645 * single list object as the value for all files from a single call.
3646 * The list object contains the Win32 process handle at [0], and a file
3647 * count at [1], which is initialized to the total number of file
3648 * handles using that list.
3649 *
3650 * This function closes whichever handle it is passed, and decrements
3651 * the file count in the dictionary for the process handle pointed to
3652 * by this file. On the last close (when the file count reaches zero),
3653 * this function will wait for the child process and then return its
3654 * exit code as the result of the close() operation. This permits the
3655 * files to be closed in any order - it is always the close() of the
3656 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003657 */
Tim Peters736aa322000-09-01 06:51:24 +00003658
3659 /* RED_FLAG 31-Aug-2000 Tim
3660 * This is always called (today!) between a pair of
3661 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3662 * macros. So the thread running this has no valid thread state, as
3663 * far as Python is concerned. However, this calls some Python API
3664 * functions that cannot be called safely without a valid thread
3665 * state, in particular PyDict_GetItem.
3666 * As a temporary hack (although it may last for years ...), we
3667 * *rely* on not having a valid thread state in this function, in
3668 * order to create our own "from scratch".
3669 * This will deadlock if _PyPclose is ever called by a thread
3670 * holding the global lock.
3671 */
3672
Fredrik Lundh56055a42000-07-23 19:47:12 +00003673static int _PyPclose(FILE *file)
3674{
Fredrik Lundh20318932000-07-26 17:29:12 +00003675 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003676 DWORD exit_code;
3677 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003678 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3679 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003680#ifdef WITH_THREAD
3681 PyInterpreterState* pInterpreterState;
3682 PyThreadState* pThreadState;
3683#endif
3684
Fredrik Lundh20318932000-07-26 17:29:12 +00003685 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003686 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003687 */
3688 result = fclose(file);
3689
Tim Peters736aa322000-09-01 06:51:24 +00003690#ifdef WITH_THREAD
3691 /* Bootstrap a valid thread state into existence. */
3692 pInterpreterState = PyInterpreterState_New();
3693 if (!pInterpreterState) {
3694 /* Well, we're hosed now! We don't have a thread
3695 * state, so can't call a nice error routine, or raise
3696 * an exception. Just die.
3697 */
3698 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003699 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003700 return -1; /* unreachable */
3701 }
3702 pThreadState = PyThreadState_New(pInterpreterState);
3703 if (!pThreadState) {
3704 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003705 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003706 return -1; /* unreachable */
3707 }
3708 /* Grab the global lock. Note that this will deadlock if the
3709 * current thread already has the lock! (see RED_FLAG comments
3710 * before this function)
3711 */
3712 PyEval_RestoreThread(pThreadState);
3713#endif
3714
Fredrik Lundh56055a42000-07-23 19:47:12 +00003715 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003716 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3717 (procObj = PyDict_GetItem(_PyPopenProcs,
3718 fileObj)) != NULL &&
3719 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3720 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3721
3722 hProcess = PyLong_AsVoidPtr(hProcessObj);
3723 file_count = PyInt_AsLong(intObj);
3724
3725 if (file_count > 1) {
3726 /* Still other files referencing process */
3727 file_count--;
3728 PyList_SetItem(procObj,1,
3729 PyInt_FromLong(file_count));
3730 } else {
3731 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003732 if (result != EOF &&
3733 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3734 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003735 /* Possible truncation here in 16-bit environments, but
3736 * real exit codes are just the lower byte in any event.
3737 */
3738 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003739 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003740 /* Indicate failure - this will cause the file object
3741 * to raise an I/O error and translate the last Win32
3742 * error code from errno. We do have a problem with
3743 * last errors that overlap the normal errno table,
3744 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003745 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003746 if (result != EOF) {
3747 /* If the error wasn't from the fclose(), then
3748 * set errno for the file object error handling.
3749 */
3750 errno = GetLastError();
3751 }
3752 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003753 }
3754
3755 /* Free up the native handle at this point */
3756 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003757 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003758
Mark Hammondb37a3732000-08-14 04:47:33 +00003759 /* Remove this file pointer from dictionary */
3760 PyDict_DelItem(_PyPopenProcs, fileObj);
3761
3762 if (PyDict_Size(_PyPopenProcs) == 0) {
3763 Py_DECREF(_PyPopenProcs);
3764 _PyPopenProcs = NULL;
3765 }
3766
3767 } /* if object retrieval ok */
3768
3769 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003770 } /* if _PyPopenProcs */
3771
Tim Peters736aa322000-09-01 06:51:24 +00003772#ifdef WITH_THREAD
3773 /* Tear down the thread & interpreter states.
3774 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003775 * call the thread clear & delete functions, and indeed insist on
3776 * doing that themselves. The lock must be held during the clear, but
3777 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003778 */
3779 PyInterpreterState_Clear(pInterpreterState);
3780 PyEval_ReleaseThread(pThreadState);
3781 PyInterpreterState_Delete(pInterpreterState);
3782#endif
3783
Fredrik Lundh56055a42000-07-23 19:47:12 +00003784 return result;
3785}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003786
3787#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003789posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003790{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003791 char *name;
3792 char *mode = "r";
3793 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003794 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003795 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003796 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003797 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003798 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003799 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003800 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003801 if (fp == NULL)
3802 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003803 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003804 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003805 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003806 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003807}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003808
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003809#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003810#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003812
Guido van Rossumb6775db1994-08-01 11:34:53 +00003813#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003814static char posix_setuid__doc__[] =
3815"setuid(uid) -> None\n\
3816Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003817static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003818posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003819{
3820 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003821 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003822 return NULL;
3823 if (setuid(uid) < 0)
3824 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003825 Py_INCREF(Py_None);
3826 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003827}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003828#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003830
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003831#ifdef HAVE_SETEUID
3832static char posix_seteuid__doc__[] =
3833"seteuid(uid) -> None\n\
3834Set the current process's effective user id.";
3835static PyObject *
3836posix_seteuid (PyObject *self, PyObject *args)
3837{
3838 int euid;
3839 if (!PyArg_ParseTuple(args, "i", &euid)) {
3840 return NULL;
3841 } else if (seteuid(euid) < 0) {
3842 return posix_error();
3843 } else {
3844 Py_INCREF(Py_None);
3845 return Py_None;
3846 }
3847}
3848#endif /* HAVE_SETEUID */
3849
3850#ifdef HAVE_SETEGID
3851static char posix_setegid__doc__[] =
3852"setegid(gid) -> None\n\
3853Set the current process's effective group id.";
3854static PyObject *
3855posix_setegid (PyObject *self, PyObject *args)
3856{
3857 int egid;
3858 if (!PyArg_ParseTuple(args, "i", &egid)) {
3859 return NULL;
3860 } else if (setegid(egid) < 0) {
3861 return posix_error();
3862 } else {
3863 Py_INCREF(Py_None);
3864 return Py_None;
3865 }
3866}
3867#endif /* HAVE_SETEGID */
3868
3869#ifdef HAVE_SETREUID
3870static char posix_setreuid__doc__[] =
3871"seteuid(ruid, euid) -> None\n\
3872Set the current process's real and effective user ids.";
3873static PyObject *
3874posix_setreuid (PyObject *self, PyObject *args)
3875{
3876 int ruid, euid;
3877 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3878 return NULL;
3879 } else if (setreuid(ruid, euid) < 0) {
3880 return posix_error();
3881 } else {
3882 Py_INCREF(Py_None);
3883 return Py_None;
3884 }
3885}
3886#endif /* HAVE_SETREUID */
3887
3888#ifdef HAVE_SETREGID
3889static char posix_setregid__doc__[] =
3890"setegid(rgid, egid) -> None\n\
3891Set the current process's real and effective group ids.";
3892static PyObject *
3893posix_setregid (PyObject *self, PyObject *args)
3894{
3895 int rgid, egid;
3896 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3897 return NULL;
3898 } else if (setregid(rgid, egid) < 0) {
3899 return posix_error();
3900 } else {
3901 Py_INCREF(Py_None);
3902 return Py_None;
3903 }
3904}
3905#endif /* HAVE_SETREGID */
3906
Guido van Rossumb6775db1994-08-01 11:34:53 +00003907#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003908static char posix_setgid__doc__[] =
3909"setgid(gid) -> None\n\
3910Set the current process's group id.";
3911
Barry Warsaw53699e91996-12-10 23:23:01 +00003912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003913posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003914{
3915 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003916 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003917 return NULL;
3918 if (setgid(gid) < 0)
3919 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003920 Py_INCREF(Py_None);
3921 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003922}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003923#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003924
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003925#ifdef HAVE_SETGROUPS
3926static char posix_setgroups__doc__[] =
3927"setgroups(list) -> None\n\
3928Set the groups of the current process to list.";
3929
3930static PyObject *
3931posix_setgroups(PyObject *self, PyObject *args)
3932{
3933 PyObject *groups;
3934 int i, len;
3935 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003936
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003937 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3938 return NULL;
3939 if (!PySequence_Check(groups)) {
3940 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3941 return NULL;
3942 }
3943 len = PySequence_Size(groups);
3944 if (len > MAX_GROUPS) {
3945 PyErr_SetString(PyExc_ValueError, "too many groups");
3946 return NULL;
3947 }
3948 for(i = 0; i < len; i++) {
3949 PyObject *elem;
3950 elem = PySequence_GetItem(groups, i);
3951 if (!elem)
3952 return NULL;
3953 if (!PyInt_Check(elem)) {
3954 PyErr_SetString(PyExc_TypeError,
3955 "groups must be integers");
3956 Py_DECREF(elem);
3957 return NULL;
3958 }
3959 /* XXX: check that value fits into gid_t. */
3960 grouplist[i] = PyInt_AsLong(elem);
3961 Py_DECREF(elem);
3962 }
3963
3964 if (setgroups(len, grouplist) < 0)
3965 return posix_error();
3966 Py_INCREF(Py_None);
3967 return Py_None;
3968}
3969#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003970
Guido van Rossumb6775db1994-08-01 11:34:53 +00003971#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003972static char posix_waitpid__doc__[] =
3973"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003974Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003975
Barry Warsaw53699e91996-12-10 23:23:01 +00003976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003977posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003978{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003979 int pid, options;
3980#ifdef UNION_WAIT
3981 union wait status;
3982#define status_i (status.w_status)
3983#else
3984 int status;
3985#define status_i status
3986#endif
3987 status_i = 0;
3988
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003989 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003990 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003991 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003992 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00003993 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003994 if (pid == -1)
3995 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003996 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003997 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003998}
3999
Tim Petersab034fa2002-02-01 11:27:43 +00004000#elif defined(HAVE_CWAIT)
4001
4002/* MS C has a variant of waitpid() that's usable for most purposes. */
4003static char posix_waitpid__doc__[] =
4004"waitpid(pid, options) -> (pid, status << 8)\n"
4005"Wait for completion of a given process. options is ignored on Windows.";
4006
4007static PyObject *
4008posix_waitpid(PyObject *self, PyObject *args)
4009{
4010 int pid, options;
4011 int status;
4012
4013 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4014 return NULL;
4015 Py_BEGIN_ALLOW_THREADS
4016 pid = _cwait(&status, pid, options);
4017 Py_END_ALLOW_THREADS
4018 if (pid == -1)
4019 return posix_error();
4020 else
4021 /* shift the status left a byte so this is more like the
4022 POSIX waitpid */
4023 return Py_BuildValue("ii", pid, status << 8);
4024}
4025#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004026
Guido van Rossumad0ee831995-03-01 10:34:45 +00004027#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004028static char posix_wait__doc__[] =
4029"wait() -> (pid, status)\n\
4030Wait for completion of a child process.";
4031
Barry Warsaw53699e91996-12-10 23:23:01 +00004032static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004033posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004034{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004035 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004036#ifdef UNION_WAIT
4037 union wait status;
4038#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004039#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004040 int status;
4041#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004042#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004043 if (!PyArg_ParseTuple(args, ":wait"))
4044 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004045 status_i = 0;
4046 Py_BEGIN_ALLOW_THREADS
4047 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004048 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004049 if (pid == -1)
4050 return posix_error();
4051 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004052 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004053#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004054}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004055#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004057
4058static char posix_lstat__doc__[] =
4059"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
4060Like stat(path), but do not follow symbolic links.";
4061
Barry Warsaw53699e91996-12-10 23:23:01 +00004062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004063posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004064{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004065#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004066 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004067#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004068 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004069#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004070}
4071
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004072
Guido van Rossumb6775db1994-08-01 11:34:53 +00004073#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004074static char posix_readlink__doc__[] =
4075"readlink(path) -> path\n\
4076Return a string representing the path to which the symbolic link points.";
4077
Barry Warsaw53699e91996-12-10 23:23:01 +00004078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004079posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004080{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004081 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004082 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004083 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004084 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004085 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004086 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004087 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004088 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004089 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004090 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004091 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004092}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004093#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004095
Guido van Rossumb6775db1994-08-01 11:34:53 +00004096#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004097static char posix_symlink__doc__[] =
4098"symlink(src, dst) -> None\n\
4099Create a symbolic link.";
4100
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004102posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004103{
Mark Hammondef8b6542001-05-13 08:04:26 +00004104 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004105}
4106#endif /* HAVE_SYMLINK */
4107
4108
4109#ifdef HAVE_TIMES
4110#ifndef HZ
4111#define HZ 60 /* Universal constant :-) */
4112#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004113
Guido van Rossumd48f2521997-12-05 22:19:34 +00004114#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4115static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004116system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004117{
4118 ULONG value = 0;
4119
4120 Py_BEGIN_ALLOW_THREADS
4121 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4122 Py_END_ALLOW_THREADS
4123
4124 return value;
4125}
4126
4127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004128posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004129{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004130 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004131 return NULL;
4132
4133 /* Currently Only Uptime is Provided -- Others Later */
4134 return Py_BuildValue("ddddd",
4135 (double)0 /* t.tms_utime / HZ */,
4136 (double)0 /* t.tms_stime / HZ */,
4137 (double)0 /* t.tms_cutime / HZ */,
4138 (double)0 /* t.tms_cstime / HZ */,
4139 (double)system_uptime() / 1000);
4140}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004141#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004143posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004144{
4145 struct tms t;
4146 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004147 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004148 return NULL;
4149 errno = 0;
4150 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004151 if (c == (clock_t) -1)
4152 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004153 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004154 (double)t.tms_utime / HZ,
4155 (double)t.tms_stime / HZ,
4156 (double)t.tms_cutime / HZ,
4157 (double)t.tms_cstime / HZ,
4158 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004159}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004160#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004161#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004162
4163
Guido van Rossum87755a21996-09-07 00:59:43 +00004164#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004165#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004167posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004168{
4169 FILETIME create, exit, kernel, user;
4170 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004171 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004172 return NULL;
4173 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004174 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4175 /* The fields of a FILETIME structure are the hi and lo part
4176 of a 64-bit value expressed in 100 nanosecond units.
4177 1e7 is one second in such units; 1e-7 the inverse.
4178 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4179 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004180 return Py_BuildValue(
4181 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004182 (double)(kernel.dwHighDateTime*429.4967296 +
4183 kernel.dwLowDateTime*1e-7),
4184 (double)(user.dwHighDateTime*429.4967296 +
4185 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004186 (double)0,
4187 (double)0,
4188 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004189}
Guido van Rossum8d665e61996-06-26 18:22:49 +00004190#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004191
4192#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00004193static char posix_times__doc__[] =
4194"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
4195Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004196#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004197
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004198
Guido van Rossumb6775db1994-08-01 11:34:53 +00004199#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004200static char posix_setsid__doc__[] =
4201"setsid() -> None\n\
4202Call the system call setsid().";
4203
Barry Warsaw53699e91996-12-10 23:23:01 +00004204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004205posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004206{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004207 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004208 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004209 if (setsid() < 0)
4210 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004211 Py_INCREF(Py_None);
4212 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004213}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004214#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004215
Guido van Rossumb6775db1994-08-01 11:34:53 +00004216#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004217static char posix_setpgid__doc__[] =
4218"setpgid(pid, pgrp) -> None\n\
4219Call the system call setpgid().";
4220
Barry Warsaw53699e91996-12-10 23:23:01 +00004221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004222posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004223{
4224 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004225 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004226 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004227 if (setpgid(pid, pgrp) < 0)
4228 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004229 Py_INCREF(Py_None);
4230 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004231}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004232#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004234
Guido van Rossumb6775db1994-08-01 11:34:53 +00004235#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004236static char posix_tcgetpgrp__doc__[] =
4237"tcgetpgrp(fd) -> pgid\n\
4238Return the process group associated with the terminal given by a fd.";
4239
Barry Warsaw53699e91996-12-10 23:23:01 +00004240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004241posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004242{
4243 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004244 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004245 return NULL;
4246 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004247 if (pgid < 0)
4248 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004249 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004250}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004251#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004252
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004253
Guido van Rossumb6775db1994-08-01 11:34:53 +00004254#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004255static char posix_tcsetpgrp__doc__[] =
4256"tcsetpgrp(fd, pgid) -> None\n\
4257Set the process group associated with the terminal given by a fd.";
4258
Barry Warsaw53699e91996-12-10 23:23:01 +00004259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004260posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004261{
4262 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004263 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004264 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004265 if (tcsetpgrp(fd, pgid) < 0)
4266 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004267 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004268 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004269}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004270#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004271
Guido van Rossum687dd131993-05-17 08:34:16 +00004272/* Functions acting on file descriptors */
4273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004274static char posix_open__doc__[] =
4275"open(filename, flag [, mode=0777]) -> fd\n\
4276Open a file (for low level IO).";
4277
Barry Warsaw53699e91996-12-10 23:23:01 +00004278static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004279posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004280{
Mark Hammondef8b6542001-05-13 08:04:26 +00004281 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004282 int flag;
4283 int mode = 0777;
4284 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004285 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004286 Py_FileSystemDefaultEncoding, &file,
4287 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004288 return NULL;
4289
Barry Warsaw53699e91996-12-10 23:23:01 +00004290 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004291 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004292 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004293 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004294 return posix_error_with_allocated_filename(file);
4295 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004296 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004297}
4298
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004299
4300static char posix_close__doc__[] =
4301"close(fd) -> None\n\
4302Close a file descriptor (for low level IO).";
4303
Barry Warsaw53699e91996-12-10 23:23:01 +00004304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004305posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004306{
4307 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004308 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004309 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004310 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004311 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004312 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004313 if (res < 0)
4314 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004315 Py_INCREF(Py_None);
4316 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004317}
4318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004319
4320static char posix_dup__doc__[] =
4321"dup(fd) -> fd2\n\
4322Return a duplicate of a file descriptor.";
4323
Barry Warsaw53699e91996-12-10 23:23:01 +00004324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004325posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004326{
4327 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004328 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004329 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004330 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004331 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004332 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004333 if (fd < 0)
4334 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004335 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004336}
4337
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004338
4339static char posix_dup2__doc__[] =
4340"dup2(fd, fd2) -> None\n\
4341Duplicate file descriptor.";
4342
Barry Warsaw53699e91996-12-10 23:23:01 +00004343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004344posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004345{
4346 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004347 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004348 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004349 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004350 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004351 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004352 if (res < 0)
4353 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004354 Py_INCREF(Py_None);
4355 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004356}
4357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004358
4359static char posix_lseek__doc__[] =
4360"lseek(fd, pos, how) -> newpos\n\
4361Set the current position of a file descriptor.";
4362
Barry Warsaw53699e91996-12-10 23:23:01 +00004363static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004364posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004365{
4366 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00004367#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004368 LONG_LONG pos, res;
4369#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004370 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004371#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004372 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004373 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004374 return NULL;
4375#ifdef SEEK_SET
4376 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4377 switch (how) {
4378 case 0: how = SEEK_SET; break;
4379 case 1: how = SEEK_CUR; break;
4380 case 2: how = SEEK_END; break;
4381 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004382#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004383
4384#if !defined(HAVE_LARGEFILE_SUPPORT)
4385 pos = PyInt_AsLong(posobj);
4386#else
4387 pos = PyLong_Check(posobj) ?
4388 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4389#endif
4390 if (PyErr_Occurred())
4391 return NULL;
4392
Barry Warsaw53699e91996-12-10 23:23:01 +00004393 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00004394#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004395 res = _lseeki64(fd, pos, how);
4396#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004397 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004398#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004399 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004400 if (res < 0)
4401 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004402
4403#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004404 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004405#else
4406 return PyLong_FromLongLong(res);
4407#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004408}
4409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004410
4411static char posix_read__doc__[] =
4412"read(fd, buffersize) -> string\n\
4413Read a file descriptor.";
4414
Barry Warsaw53699e91996-12-10 23:23:01 +00004415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004416posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004417{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004418 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004419 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004420 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004421 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004422 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004423 if (buffer == NULL)
4424 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004425 Py_BEGIN_ALLOW_THREADS
4426 n = read(fd, PyString_AsString(buffer), size);
4427 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004428 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004429 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004430 return posix_error();
4431 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004432 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004433 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004434 return buffer;
4435}
4436
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004437
4438static char posix_write__doc__[] =
4439"write(fd, string) -> byteswritten\n\
4440Write a string to a file descriptor.";
4441
Barry Warsaw53699e91996-12-10 23:23:01 +00004442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004443posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004444{
4445 int fd, size;
4446 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004447 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004448 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004449 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004450 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004451 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004452 if (size < 0)
4453 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004454 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004455}
4456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004457
4458static char posix_fstat__doc__[]=
4459"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
4460Like stat(), but for an open file descriptor.";
4461
Barry Warsaw53699e91996-12-10 23:23:01 +00004462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004463posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004464{
4465 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004466 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004467 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004468 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004469 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004470 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004471 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004472 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004473 if (res != 0)
4474 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004475
Fred Drake699f3522000-06-29 21:12:41 +00004476 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004477}
4478
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004479
4480static char posix_fdopen__doc__[] =
4481"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
4482Return an open file object connected to a file descriptor.";
4483
Barry Warsaw53699e91996-12-10 23:23:01 +00004484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004485posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004486{
Guido van Rossum687dd131993-05-17 08:34:16 +00004487 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004488 char *mode = "r";
4489 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004490 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004491 PyObject *f;
4492 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004493 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004494
Barry Warsaw53699e91996-12-10 23:23:01 +00004495 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004496 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004497 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004498 if (fp == NULL)
4499 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004500 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004501 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004502 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004503 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004504}
4505
Skip Montanaro1517d842000-07-19 14:34:14 +00004506static char posix_isatty__doc__[] =
4507"isatty(fd) -> Boolean\n\
4508Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00004509connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00004510
4511static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004512posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004513{
4514 int fd;
4515 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4516 return NULL;
4517 return Py_BuildValue("i", isatty(fd));
4518}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004519
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004520#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004521static char posix_pipe__doc__[] =
4522"pipe() -> (read_end, write_end)\n\
4523Create a pipe.";
4524
Barry Warsaw53699e91996-12-10 23:23:01 +00004525static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004526posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004527{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004528#if defined(PYOS_OS2)
4529 HFILE read, write;
4530 APIRET rc;
4531
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004532 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004533 return NULL;
4534
4535 Py_BEGIN_ALLOW_THREADS
4536 rc = DosCreatePipe( &read, &write, 4096);
4537 Py_END_ALLOW_THREADS
4538 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004539 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004540
4541 return Py_BuildValue("(ii)", read, write);
4542#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00004543#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00004544 int fds[2];
4545 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004546 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004547 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004548 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004549 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004550 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004551 if (res != 0)
4552 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004553 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004554#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00004555 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004556 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004557 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004558 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004559 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004560 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004561 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004562 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004563 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004564 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004565 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4566 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004567 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004568#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004569#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004570}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004571#endif /* HAVE_PIPE */
4572
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004573
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004574#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004575static char posix_mkfifo__doc__[] =
4576"mkfifo(file, [, mode=0666]) -> None\n\
4577Create a FIFO (a POSIX named pipe).";
4578
Barry Warsaw53699e91996-12-10 23:23:01 +00004579static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004580posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004581{
4582 char *file;
4583 int mode = 0666;
4584 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004585 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004586 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004587 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004588 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004589 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004590 if (res < 0)
4591 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004592 Py_INCREF(Py_None);
4593 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004594}
4595#endif
4596
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004597
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004598#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004599static char posix_ftruncate__doc__[] =
4600"ftruncate(fd, length) -> None\n\
4601Truncate a file to a specified length.";
4602
Barry Warsaw53699e91996-12-10 23:23:01 +00004603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004604posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004605{
4606 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004607 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004608 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004609 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004610
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004611 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004612 return NULL;
4613
4614#if !defined(HAVE_LARGEFILE_SUPPORT)
4615 length = PyInt_AsLong(lenobj);
4616#else
4617 length = PyLong_Check(lenobj) ?
4618 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4619#endif
4620 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004621 return NULL;
4622
Barry Warsaw53699e91996-12-10 23:23:01 +00004623 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004624 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004625 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004626 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004627 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004628 return NULL;
4629 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004630 Py_INCREF(Py_None);
4631 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004632}
4633#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004634
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004635#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004636static char posix_putenv__doc__[] =
4637"putenv(key, value) -> None\n\
4638Change or add an environment variable.";
4639
Fred Drake762e2061999-08-26 17:23:54 +00004640/* Save putenv() parameters as values here, so we can collect them when they
4641 * get re-set with another call for the same key. */
4642static PyObject *posix_putenv_garbage;
4643
Tim Peters5aa91602002-01-30 05:46:57 +00004644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004645posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004646{
4647 char *s1, *s2;
4648 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004649 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004650 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004651
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004652 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004653 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004654
4655#if defined(PYOS_OS2)
4656 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4657 APIRET rc;
4658
4659 if (strlen(s2) == 0) /* If New Value is an Empty String */
4660 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4661
4662 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4663 if (rc != NO_ERROR)
4664 return os2_error(rc);
4665
4666 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4667 APIRET rc;
4668
4669 if (strlen(s2) == 0) /* If New Value is an Empty String */
4670 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4671
4672 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4673 if (rc != NO_ERROR)
4674 return os2_error(rc);
4675 } else {
4676#endif
4677
Fred Drake762e2061999-08-26 17:23:54 +00004678 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004679 len = strlen(s1) + strlen(s2) + 2;
4680 /* len includes space for a trailing \0; the size arg to
4681 PyString_FromStringAndSize does not count that */
4682 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004683 if (newstr == NULL)
4684 return PyErr_NoMemory();
4685 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004686 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004687 if (putenv(new)) {
4688 posix_error();
4689 return NULL;
4690 }
Fred Drake762e2061999-08-26 17:23:54 +00004691 /* Install the first arg and newstr in posix_putenv_garbage;
4692 * this will cause previous value to be collected. This has to
4693 * happen after the real putenv() call because the old value
4694 * was still accessible until then. */
4695 if (PyDict_SetItem(posix_putenv_garbage,
4696 PyTuple_GET_ITEM(args, 0), newstr)) {
4697 /* really not much we can do; just leak */
4698 PyErr_Clear();
4699 }
4700 else {
4701 Py_DECREF(newstr);
4702 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004703
4704#if defined(PYOS_OS2)
4705 }
4706#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004707 Py_INCREF(Py_None);
4708 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004709}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004710#endif /* putenv */
4711
Guido van Rossumc524d952001-10-19 01:31:59 +00004712#ifdef HAVE_UNSETENV
4713static char posix_unsetenv__doc__[] =
4714"unsetenv(key) -> None\n\
4715Delete an environment variable.";
4716
4717static PyObject *
4718posix_unsetenv(PyObject *self, PyObject *args)
4719{
4720 char *s1;
4721
4722 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4723 return NULL;
4724
4725 unsetenv(s1);
4726
4727 /* Remove the key from posix_putenv_garbage;
4728 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004729 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004730 * old value was still accessible until then.
4731 */
4732 if (PyDict_DelItem(posix_putenv_garbage,
4733 PyTuple_GET_ITEM(args, 0))) {
4734 /* really not much we can do; just leak */
4735 PyErr_Clear();
4736 }
4737
4738 Py_INCREF(Py_None);
4739 return Py_None;
4740}
4741#endif /* unsetenv */
4742
Guido van Rossumb6a47161997-09-15 22:54:34 +00004743#ifdef HAVE_STRERROR
4744static char posix_strerror__doc__[] =
4745"strerror(code) -> string\n\
4746Translate an error code to a message string.";
4747
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004748static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004749posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004750{
4751 int code;
4752 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004753 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004754 return NULL;
4755 message = strerror(code);
4756 if (message == NULL) {
4757 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004758 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004759 return NULL;
4760 }
4761 return PyString_FromString(message);
4762}
4763#endif /* strerror */
4764
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004765
Guido van Rossumc9641791998-08-04 15:26:23 +00004766#ifdef HAVE_SYS_WAIT_H
4767
4768#ifdef WIFSTOPPED
4769static char posix_WIFSTOPPED__doc__[] =
4770"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004771Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004772
4773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004774posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004775{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004776#ifdef UNION_WAIT
4777 union wait status;
4778#define status_i (status.w_status)
4779#else
4780 int status;
4781#define status_i status
4782#endif
4783 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004784
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004785 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004786 {
4787 return NULL;
4788 }
Tim Peters5aa91602002-01-30 05:46:57 +00004789
Guido van Rossumc9641791998-08-04 15:26:23 +00004790 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004791#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004792}
4793#endif /* WIFSTOPPED */
4794
4795#ifdef WIFSIGNALED
4796static char posix_WIFSIGNALED__doc__[] =
4797"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004798Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004799
4800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004801posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004802{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004803#ifdef UNION_WAIT
4804 union wait status;
4805#define status_i (status.w_status)
4806#else
4807 int status;
4808#define status_i status
4809#endif
4810 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004811
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004812 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004813 {
4814 return NULL;
4815 }
Tim Peters5aa91602002-01-30 05:46:57 +00004816
Guido van Rossumc9641791998-08-04 15:26:23 +00004817 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004818#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004819}
4820#endif /* WIFSIGNALED */
4821
4822#ifdef WIFEXITED
4823static char posix_WIFEXITED__doc__[] =
4824"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004825Return true if the process returning 'status' exited using the exit()\n\
4826system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004827
4828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004829posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004830{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004831#ifdef UNION_WAIT
4832 union wait status;
4833#define status_i (status.w_status)
4834#else
4835 int status;
4836#define status_i status
4837#endif
4838 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004839
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004840 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004841 {
4842 return NULL;
4843 }
Tim Peters5aa91602002-01-30 05:46:57 +00004844
Guido van Rossumc9641791998-08-04 15:26:23 +00004845 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004846#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004847}
4848#endif /* WIFEXITED */
4849
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004850#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004851static char posix_WEXITSTATUS__doc__[] =
4852"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004853Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004854
4855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004856posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004857{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004858#ifdef UNION_WAIT
4859 union wait status;
4860#define status_i (status.w_status)
4861#else
4862 int status;
4863#define status_i status
4864#endif
4865 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004866
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004867 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004868 {
4869 return NULL;
4870 }
Tim Peters5aa91602002-01-30 05:46:57 +00004871
Guido van Rossumc9641791998-08-04 15:26:23 +00004872 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004873#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004874}
4875#endif /* WEXITSTATUS */
4876
4877#ifdef WTERMSIG
4878static char posix_WTERMSIG__doc__[] =
4879"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004880Return the signal that terminated the process that provided the 'status'\n\
4881value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004882
4883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004884posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004885{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004886#ifdef UNION_WAIT
4887 union wait status;
4888#define status_i (status.w_status)
4889#else
4890 int status;
4891#define status_i status
4892#endif
4893 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004894
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004895 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004896 {
4897 return NULL;
4898 }
Tim Peters5aa91602002-01-30 05:46:57 +00004899
Guido van Rossumc9641791998-08-04 15:26:23 +00004900 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004901#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004902}
4903#endif /* WTERMSIG */
4904
4905#ifdef WSTOPSIG
4906static char posix_WSTOPSIG__doc__[] =
4907"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004908Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004909
4910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004911posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004912{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004913#ifdef UNION_WAIT
4914 union wait status;
4915#define status_i (status.w_status)
4916#else
4917 int status;
4918#define status_i status
4919#endif
4920 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004921
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004922 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004923 {
4924 return NULL;
4925 }
Tim Peters5aa91602002-01-30 05:46:57 +00004926
Guido van Rossumc9641791998-08-04 15:26:23 +00004927 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004928#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004929}
4930#endif /* WSTOPSIG */
4931
4932#endif /* HAVE_SYS_WAIT_H */
4933
4934
Guido van Rossum94f6f721999-01-06 18:42:14 +00004935#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004936#ifdef _SCO_DS
4937/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4938 needed definitions in sys/statvfs.h */
4939#define _SVID3
4940#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004941#include <sys/statvfs.h>
4942
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004943static PyObject*
4944_pystatvfs_fromstructstatvfs(struct statvfs st) {
4945 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4946 if (v == NULL)
4947 return NULL;
4948
4949#if !defined(HAVE_LARGEFILE_SUPPORT)
4950 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4951 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4952 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4953 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4954 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4955 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4956 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4957 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4958 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4959 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4960#else
4961 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4962 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00004963 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004964 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00004965 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004966 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4967 PyStructSequence_SET_ITEM(v, 4,
4968 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00004969 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004970 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00004971 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004972 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00004973 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004974 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4975 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4976 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4977#endif
4978
4979 return v;
4980}
4981
Guido van Rossum94f6f721999-01-06 18:42:14 +00004982static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004983"fstatvfs(fd) -> \n\
4984 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004985Perform an fstatvfs system call on the given fd.";
4986
4987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004988posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004989{
4990 int fd, res;
4991 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004992
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004993 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004994 return NULL;
4995 Py_BEGIN_ALLOW_THREADS
4996 res = fstatvfs(fd, &st);
4997 Py_END_ALLOW_THREADS
4998 if (res != 0)
4999 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005000
5001 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005002}
5003#endif /* HAVE_FSTATVFS */
5004
5005
5006#if defined(HAVE_STATVFS)
5007#include <sys/statvfs.h>
5008
5009static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005010"statvfs(path) -> \n\
5011 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005012Perform a statvfs system call on the given path.";
5013
5014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005015posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005016{
5017 char *path;
5018 int res;
5019 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005020 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005021 return NULL;
5022 Py_BEGIN_ALLOW_THREADS
5023 res = statvfs(path, &st);
5024 Py_END_ALLOW_THREADS
5025 if (res != 0)
5026 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005027
5028 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005029}
5030#endif /* HAVE_STATVFS */
5031
5032
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005033#ifdef HAVE_TEMPNAM
5034static char posix_tempnam__doc__[] = "\
5035tempnam([dir[, prefix]]) -> string\n\
5036Return a unique name for a temporary file.\n\
5037The directory and a short may be specified as strings; they may be omitted\n\
5038or None if not needed.";
5039
5040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005041posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005042{
5043 PyObject *result = NULL;
5044 char *dir = NULL;
5045 char *pfx = NULL;
5046 char *name;
5047
5048 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5049 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005050
5051 if (PyErr_Warn(PyExc_RuntimeWarning,
5052 "tempnam is a potential security risk to your program") < 0)
5053 return NULL;
5054
Fred Drake78b71c22001-07-17 20:37:36 +00005055#ifdef MS_WIN32
5056 name = _tempnam(dir, pfx);
5057#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005058 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005059#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005060 if (name == NULL)
5061 return PyErr_NoMemory();
5062 result = PyString_FromString(name);
5063 free(name);
5064 return result;
5065}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005066#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005067
5068
5069#ifdef HAVE_TMPFILE
5070static char posix_tmpfile__doc__[] = "\
5071tmpfile() -> file object\n\
5072Create a temporary file with no directory entries.";
5073
5074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005075posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005076{
5077 FILE *fp;
5078
5079 if (!PyArg_ParseTuple(args, ":tmpfile"))
5080 return NULL;
5081 fp = tmpfile();
5082 if (fp == NULL)
5083 return posix_error();
5084 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
5085}
5086#endif
5087
5088
5089#ifdef HAVE_TMPNAM
5090static char posix_tmpnam__doc__[] = "\
5091tmpnam() -> string\n\
5092Return a unique name for a temporary file.";
5093
5094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005095posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005096{
5097 char buffer[L_tmpnam];
5098 char *name;
5099
5100 if (!PyArg_ParseTuple(args, ":tmpnam"))
5101 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005102
5103 if (PyErr_Warn(PyExc_RuntimeWarning,
5104 "tmpnam is a potential security risk to your program") < 0)
5105 return NULL;
5106
Greg Wardb48bc172000-03-01 21:51:56 +00005107#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005108 name = tmpnam_r(buffer);
5109#else
5110 name = tmpnam(buffer);
5111#endif
5112 if (name == NULL) {
5113 PyErr_SetObject(PyExc_OSError,
5114 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005115#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005116 "unexpected NULL from tmpnam_r"
5117#else
5118 "unexpected NULL from tmpnam"
5119#endif
5120 ));
5121 return NULL;
5122 }
5123 return PyString_FromString(buffer);
5124}
5125#endif
5126
5127
Fred Drakec9680921999-12-13 16:37:25 +00005128/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5129 * It maps strings representing configuration variable names to
5130 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005131 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005132 * rarely-used constants. There are three separate tables that use
5133 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005134 *
5135 * This code is always included, even if none of the interfaces that
5136 * need it are included. The #if hackery needed to avoid it would be
5137 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005138 */
5139struct constdef {
5140 char *name;
5141 long value;
5142};
5143
Fred Drake12c6e2d1999-12-14 21:25:03 +00005144static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005145conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5146 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005147{
5148 if (PyInt_Check(arg)) {
5149 *valuep = PyInt_AS_LONG(arg);
5150 return 1;
5151 }
5152 if (PyString_Check(arg)) {
5153 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005154 size_t lo = 0;
5155 size_t mid;
5156 size_t hi = tablesize;
5157 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005158 char *confname = PyString_AS_STRING(arg);
5159 while (lo < hi) {
5160 mid = (lo + hi) / 2;
5161 cmp = strcmp(confname, table[mid].name);
5162 if (cmp < 0)
5163 hi = mid;
5164 else if (cmp > 0)
5165 lo = mid + 1;
5166 else {
5167 *valuep = table[mid].value;
5168 return 1;
5169 }
5170 }
5171 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5172 }
5173 else
5174 PyErr_SetString(PyExc_TypeError,
5175 "configuration names must be strings or integers");
5176 return 0;
5177}
5178
5179
5180#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5181static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005182#ifdef _PC_ABI_AIO_XFER_MAX
5183 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5184#endif
5185#ifdef _PC_ABI_ASYNC_IO
5186 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5187#endif
Fred Drakec9680921999-12-13 16:37:25 +00005188#ifdef _PC_ASYNC_IO
5189 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5190#endif
5191#ifdef _PC_CHOWN_RESTRICTED
5192 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5193#endif
5194#ifdef _PC_FILESIZEBITS
5195 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5196#endif
5197#ifdef _PC_LAST
5198 {"PC_LAST", _PC_LAST},
5199#endif
5200#ifdef _PC_LINK_MAX
5201 {"PC_LINK_MAX", _PC_LINK_MAX},
5202#endif
5203#ifdef _PC_MAX_CANON
5204 {"PC_MAX_CANON", _PC_MAX_CANON},
5205#endif
5206#ifdef _PC_MAX_INPUT
5207 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5208#endif
5209#ifdef _PC_NAME_MAX
5210 {"PC_NAME_MAX", _PC_NAME_MAX},
5211#endif
5212#ifdef _PC_NO_TRUNC
5213 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5214#endif
5215#ifdef _PC_PATH_MAX
5216 {"PC_PATH_MAX", _PC_PATH_MAX},
5217#endif
5218#ifdef _PC_PIPE_BUF
5219 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5220#endif
5221#ifdef _PC_PRIO_IO
5222 {"PC_PRIO_IO", _PC_PRIO_IO},
5223#endif
5224#ifdef _PC_SOCK_MAXBUF
5225 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5226#endif
5227#ifdef _PC_SYNC_IO
5228 {"PC_SYNC_IO", _PC_SYNC_IO},
5229#endif
5230#ifdef _PC_VDISABLE
5231 {"PC_VDISABLE", _PC_VDISABLE},
5232#endif
5233};
5234
Fred Drakec9680921999-12-13 16:37:25 +00005235static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005236conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005237{
5238 return conv_confname(arg, valuep, posix_constants_pathconf,
5239 sizeof(posix_constants_pathconf)
5240 / sizeof(struct constdef));
5241}
5242#endif
5243
5244#ifdef HAVE_FPATHCONF
5245static char posix_fpathconf__doc__[] = "\
5246fpathconf(fd, name) -> integer\n\
5247Return the configuration limit name for the file descriptor fd.\n\
5248If there is no limit, return -1.";
5249
5250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005251posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005252{
5253 PyObject *result = NULL;
5254 int name, fd;
5255
Fred Drake12c6e2d1999-12-14 21:25:03 +00005256 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5257 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005258 long limit;
5259
5260 errno = 0;
5261 limit = fpathconf(fd, name);
5262 if (limit == -1 && errno != 0)
5263 posix_error();
5264 else
5265 result = PyInt_FromLong(limit);
5266 }
5267 return result;
5268}
5269#endif
5270
5271
5272#ifdef HAVE_PATHCONF
5273static char posix_pathconf__doc__[] = "\
5274pathconf(path, name) -> integer\n\
5275Return the configuration limit name for the file or directory path.\n\
5276If there is no limit, return -1.";
5277
5278static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005279posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005280{
5281 PyObject *result = NULL;
5282 int name;
5283 char *path;
5284
5285 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5286 conv_path_confname, &name)) {
5287 long limit;
5288
5289 errno = 0;
5290 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005291 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005292 if (errno == EINVAL)
5293 /* could be a path or name problem */
5294 posix_error();
5295 else
5296 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005297 }
Fred Drakec9680921999-12-13 16:37:25 +00005298 else
5299 result = PyInt_FromLong(limit);
5300 }
5301 return result;
5302}
5303#endif
5304
5305#ifdef HAVE_CONFSTR
5306static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005307#ifdef _CS_ARCHITECTURE
5308 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5309#endif
5310#ifdef _CS_HOSTNAME
5311 {"CS_HOSTNAME", _CS_HOSTNAME},
5312#endif
5313#ifdef _CS_HW_PROVIDER
5314 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5315#endif
5316#ifdef _CS_HW_SERIAL
5317 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5318#endif
5319#ifdef _CS_INITTAB_NAME
5320 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5321#endif
Fred Drakec9680921999-12-13 16:37:25 +00005322#ifdef _CS_LFS64_CFLAGS
5323 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5324#endif
5325#ifdef _CS_LFS64_LDFLAGS
5326 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5327#endif
5328#ifdef _CS_LFS64_LIBS
5329 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5330#endif
5331#ifdef _CS_LFS64_LINTFLAGS
5332 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5333#endif
5334#ifdef _CS_LFS_CFLAGS
5335 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5336#endif
5337#ifdef _CS_LFS_LDFLAGS
5338 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5339#endif
5340#ifdef _CS_LFS_LIBS
5341 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5342#endif
5343#ifdef _CS_LFS_LINTFLAGS
5344 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5345#endif
Fred Draked86ed291999-12-15 15:34:33 +00005346#ifdef _CS_MACHINE
5347 {"CS_MACHINE", _CS_MACHINE},
5348#endif
Fred Drakec9680921999-12-13 16:37:25 +00005349#ifdef _CS_PATH
5350 {"CS_PATH", _CS_PATH},
5351#endif
Fred Draked86ed291999-12-15 15:34:33 +00005352#ifdef _CS_RELEASE
5353 {"CS_RELEASE", _CS_RELEASE},
5354#endif
5355#ifdef _CS_SRPC_DOMAIN
5356 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5357#endif
5358#ifdef _CS_SYSNAME
5359 {"CS_SYSNAME", _CS_SYSNAME},
5360#endif
5361#ifdef _CS_VERSION
5362 {"CS_VERSION", _CS_VERSION},
5363#endif
Fred Drakec9680921999-12-13 16:37:25 +00005364#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5365 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5366#endif
5367#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5368 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5369#endif
5370#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5371 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5372#endif
5373#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5374 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5375#endif
5376#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5377 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5378#endif
5379#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5380 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5381#endif
5382#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5383 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5384#endif
5385#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5386 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5387#endif
5388#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5389 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5390#endif
5391#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5392 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5393#endif
5394#ifdef _CS_XBS5_LP64_OFF64_LIBS
5395 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5396#endif
5397#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5398 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5399#endif
5400#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5401 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5402#endif
5403#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5404 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5405#endif
5406#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5407 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5408#endif
5409#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5410 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5411#endif
Fred Draked86ed291999-12-15 15:34:33 +00005412#ifdef _MIPS_CS_AVAIL_PROCESSORS
5413 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5414#endif
5415#ifdef _MIPS_CS_BASE
5416 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5417#endif
5418#ifdef _MIPS_CS_HOSTID
5419 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5420#endif
5421#ifdef _MIPS_CS_HW_NAME
5422 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5423#endif
5424#ifdef _MIPS_CS_NUM_PROCESSORS
5425 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5426#endif
5427#ifdef _MIPS_CS_OSREL_MAJ
5428 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5429#endif
5430#ifdef _MIPS_CS_OSREL_MIN
5431 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5432#endif
5433#ifdef _MIPS_CS_OSREL_PATCH
5434 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5435#endif
5436#ifdef _MIPS_CS_OS_NAME
5437 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5438#endif
5439#ifdef _MIPS_CS_OS_PROVIDER
5440 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5441#endif
5442#ifdef _MIPS_CS_PROCESSORS
5443 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5444#endif
5445#ifdef _MIPS_CS_SERIAL
5446 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5447#endif
5448#ifdef _MIPS_CS_VENDOR
5449 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5450#endif
Fred Drakec9680921999-12-13 16:37:25 +00005451};
5452
5453static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005454conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005455{
5456 return conv_confname(arg, valuep, posix_constants_confstr,
5457 sizeof(posix_constants_confstr)
5458 / sizeof(struct constdef));
5459}
5460
5461static char posix_confstr__doc__[] = "\
5462confstr(name) -> string\n\
5463Return a string-valued system configuration variable.";
5464
5465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005466posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005467{
5468 PyObject *result = NULL;
5469 int name;
5470 char buffer[64];
5471
5472 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5473 int len = confstr(name, buffer, sizeof(buffer));
5474
Fred Drakec9680921999-12-13 16:37:25 +00005475 errno = 0;
5476 if (len == 0) {
5477 if (errno != 0)
5478 posix_error();
5479 else
5480 result = PyString_FromString("");
5481 }
5482 else {
5483 if (len >= sizeof(buffer)) {
5484 result = PyString_FromStringAndSize(NULL, len);
5485 if (result != NULL)
5486 confstr(name, PyString_AS_STRING(result), len+1);
5487 }
5488 else
5489 result = PyString_FromString(buffer);
5490 }
5491 }
5492 return result;
5493}
5494#endif
5495
5496
5497#ifdef HAVE_SYSCONF
5498static struct constdef posix_constants_sysconf[] = {
5499#ifdef _SC_2_CHAR_TERM
5500 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5501#endif
5502#ifdef _SC_2_C_BIND
5503 {"SC_2_C_BIND", _SC_2_C_BIND},
5504#endif
5505#ifdef _SC_2_C_DEV
5506 {"SC_2_C_DEV", _SC_2_C_DEV},
5507#endif
5508#ifdef _SC_2_C_VERSION
5509 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5510#endif
5511#ifdef _SC_2_FORT_DEV
5512 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5513#endif
5514#ifdef _SC_2_FORT_RUN
5515 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5516#endif
5517#ifdef _SC_2_LOCALEDEF
5518 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5519#endif
5520#ifdef _SC_2_SW_DEV
5521 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5522#endif
5523#ifdef _SC_2_UPE
5524 {"SC_2_UPE", _SC_2_UPE},
5525#endif
5526#ifdef _SC_2_VERSION
5527 {"SC_2_VERSION", _SC_2_VERSION},
5528#endif
Fred Draked86ed291999-12-15 15:34:33 +00005529#ifdef _SC_ABI_ASYNCHRONOUS_IO
5530 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5531#endif
5532#ifdef _SC_ACL
5533 {"SC_ACL", _SC_ACL},
5534#endif
Fred Drakec9680921999-12-13 16:37:25 +00005535#ifdef _SC_AIO_LISTIO_MAX
5536 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5537#endif
Fred Drakec9680921999-12-13 16:37:25 +00005538#ifdef _SC_AIO_MAX
5539 {"SC_AIO_MAX", _SC_AIO_MAX},
5540#endif
5541#ifdef _SC_AIO_PRIO_DELTA_MAX
5542 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5543#endif
5544#ifdef _SC_ARG_MAX
5545 {"SC_ARG_MAX", _SC_ARG_MAX},
5546#endif
5547#ifdef _SC_ASYNCHRONOUS_IO
5548 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5549#endif
5550#ifdef _SC_ATEXIT_MAX
5551 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5552#endif
Fred Draked86ed291999-12-15 15:34:33 +00005553#ifdef _SC_AUDIT
5554 {"SC_AUDIT", _SC_AUDIT},
5555#endif
Fred Drakec9680921999-12-13 16:37:25 +00005556#ifdef _SC_AVPHYS_PAGES
5557 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5558#endif
5559#ifdef _SC_BC_BASE_MAX
5560 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5561#endif
5562#ifdef _SC_BC_DIM_MAX
5563 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5564#endif
5565#ifdef _SC_BC_SCALE_MAX
5566 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5567#endif
5568#ifdef _SC_BC_STRING_MAX
5569 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5570#endif
Fred Draked86ed291999-12-15 15:34:33 +00005571#ifdef _SC_CAP
5572 {"SC_CAP", _SC_CAP},
5573#endif
Fred Drakec9680921999-12-13 16:37:25 +00005574#ifdef _SC_CHARCLASS_NAME_MAX
5575 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5576#endif
5577#ifdef _SC_CHAR_BIT
5578 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5579#endif
5580#ifdef _SC_CHAR_MAX
5581 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5582#endif
5583#ifdef _SC_CHAR_MIN
5584 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5585#endif
5586#ifdef _SC_CHILD_MAX
5587 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5588#endif
5589#ifdef _SC_CLK_TCK
5590 {"SC_CLK_TCK", _SC_CLK_TCK},
5591#endif
5592#ifdef _SC_COHER_BLKSZ
5593 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5594#endif
5595#ifdef _SC_COLL_WEIGHTS_MAX
5596 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5597#endif
5598#ifdef _SC_DCACHE_ASSOC
5599 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5600#endif
5601#ifdef _SC_DCACHE_BLKSZ
5602 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5603#endif
5604#ifdef _SC_DCACHE_LINESZ
5605 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5606#endif
5607#ifdef _SC_DCACHE_SZ
5608 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5609#endif
5610#ifdef _SC_DCACHE_TBLKSZ
5611 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5612#endif
5613#ifdef _SC_DELAYTIMER_MAX
5614 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5615#endif
5616#ifdef _SC_EQUIV_CLASS_MAX
5617 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5618#endif
5619#ifdef _SC_EXPR_NEST_MAX
5620 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5621#endif
5622#ifdef _SC_FSYNC
5623 {"SC_FSYNC", _SC_FSYNC},
5624#endif
5625#ifdef _SC_GETGR_R_SIZE_MAX
5626 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5627#endif
5628#ifdef _SC_GETPW_R_SIZE_MAX
5629 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5630#endif
5631#ifdef _SC_ICACHE_ASSOC
5632 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5633#endif
5634#ifdef _SC_ICACHE_BLKSZ
5635 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5636#endif
5637#ifdef _SC_ICACHE_LINESZ
5638 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5639#endif
5640#ifdef _SC_ICACHE_SZ
5641 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5642#endif
Fred Draked86ed291999-12-15 15:34:33 +00005643#ifdef _SC_INF
5644 {"SC_INF", _SC_INF},
5645#endif
Fred Drakec9680921999-12-13 16:37:25 +00005646#ifdef _SC_INT_MAX
5647 {"SC_INT_MAX", _SC_INT_MAX},
5648#endif
5649#ifdef _SC_INT_MIN
5650 {"SC_INT_MIN", _SC_INT_MIN},
5651#endif
5652#ifdef _SC_IOV_MAX
5653 {"SC_IOV_MAX", _SC_IOV_MAX},
5654#endif
Fred Draked86ed291999-12-15 15:34:33 +00005655#ifdef _SC_IP_SECOPTS
5656 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5657#endif
Fred Drakec9680921999-12-13 16:37:25 +00005658#ifdef _SC_JOB_CONTROL
5659 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5660#endif
Fred Draked86ed291999-12-15 15:34:33 +00005661#ifdef _SC_KERN_POINTERS
5662 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5663#endif
5664#ifdef _SC_KERN_SIM
5665 {"SC_KERN_SIM", _SC_KERN_SIM},
5666#endif
Fred Drakec9680921999-12-13 16:37:25 +00005667#ifdef _SC_LINE_MAX
5668 {"SC_LINE_MAX", _SC_LINE_MAX},
5669#endif
5670#ifdef _SC_LOGIN_NAME_MAX
5671 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5672#endif
5673#ifdef _SC_LOGNAME_MAX
5674 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5675#endif
5676#ifdef _SC_LONG_BIT
5677 {"SC_LONG_BIT", _SC_LONG_BIT},
5678#endif
Fred Draked86ed291999-12-15 15:34:33 +00005679#ifdef _SC_MAC
5680 {"SC_MAC", _SC_MAC},
5681#endif
Fred Drakec9680921999-12-13 16:37:25 +00005682#ifdef _SC_MAPPED_FILES
5683 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5684#endif
5685#ifdef _SC_MAXPID
5686 {"SC_MAXPID", _SC_MAXPID},
5687#endif
5688#ifdef _SC_MB_LEN_MAX
5689 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5690#endif
5691#ifdef _SC_MEMLOCK
5692 {"SC_MEMLOCK", _SC_MEMLOCK},
5693#endif
5694#ifdef _SC_MEMLOCK_RANGE
5695 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5696#endif
5697#ifdef _SC_MEMORY_PROTECTION
5698 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5699#endif
5700#ifdef _SC_MESSAGE_PASSING
5701 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5702#endif
Fred Draked86ed291999-12-15 15:34:33 +00005703#ifdef _SC_MMAP_FIXED_ALIGNMENT
5704 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5705#endif
Fred Drakec9680921999-12-13 16:37:25 +00005706#ifdef _SC_MQ_OPEN_MAX
5707 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5708#endif
5709#ifdef _SC_MQ_PRIO_MAX
5710 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5711#endif
Fred Draked86ed291999-12-15 15:34:33 +00005712#ifdef _SC_NACLS_MAX
5713 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5714#endif
Fred Drakec9680921999-12-13 16:37:25 +00005715#ifdef _SC_NGROUPS_MAX
5716 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5717#endif
5718#ifdef _SC_NL_ARGMAX
5719 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5720#endif
5721#ifdef _SC_NL_LANGMAX
5722 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5723#endif
5724#ifdef _SC_NL_MSGMAX
5725 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5726#endif
5727#ifdef _SC_NL_NMAX
5728 {"SC_NL_NMAX", _SC_NL_NMAX},
5729#endif
5730#ifdef _SC_NL_SETMAX
5731 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5732#endif
5733#ifdef _SC_NL_TEXTMAX
5734 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5735#endif
5736#ifdef _SC_NPROCESSORS_CONF
5737 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5738#endif
5739#ifdef _SC_NPROCESSORS_ONLN
5740 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5741#endif
Fred Draked86ed291999-12-15 15:34:33 +00005742#ifdef _SC_NPROC_CONF
5743 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5744#endif
5745#ifdef _SC_NPROC_ONLN
5746 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5747#endif
Fred Drakec9680921999-12-13 16:37:25 +00005748#ifdef _SC_NZERO
5749 {"SC_NZERO", _SC_NZERO},
5750#endif
5751#ifdef _SC_OPEN_MAX
5752 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5753#endif
5754#ifdef _SC_PAGESIZE
5755 {"SC_PAGESIZE", _SC_PAGESIZE},
5756#endif
5757#ifdef _SC_PAGE_SIZE
5758 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5759#endif
5760#ifdef _SC_PASS_MAX
5761 {"SC_PASS_MAX", _SC_PASS_MAX},
5762#endif
5763#ifdef _SC_PHYS_PAGES
5764 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5765#endif
5766#ifdef _SC_PII
5767 {"SC_PII", _SC_PII},
5768#endif
5769#ifdef _SC_PII_INTERNET
5770 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5771#endif
5772#ifdef _SC_PII_INTERNET_DGRAM
5773 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5774#endif
5775#ifdef _SC_PII_INTERNET_STREAM
5776 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5777#endif
5778#ifdef _SC_PII_OSI
5779 {"SC_PII_OSI", _SC_PII_OSI},
5780#endif
5781#ifdef _SC_PII_OSI_CLTS
5782 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5783#endif
5784#ifdef _SC_PII_OSI_COTS
5785 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5786#endif
5787#ifdef _SC_PII_OSI_M
5788 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5789#endif
5790#ifdef _SC_PII_SOCKET
5791 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5792#endif
5793#ifdef _SC_PII_XTI
5794 {"SC_PII_XTI", _SC_PII_XTI},
5795#endif
5796#ifdef _SC_POLL
5797 {"SC_POLL", _SC_POLL},
5798#endif
5799#ifdef _SC_PRIORITIZED_IO
5800 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5801#endif
5802#ifdef _SC_PRIORITY_SCHEDULING
5803 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5804#endif
5805#ifdef _SC_REALTIME_SIGNALS
5806 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5807#endif
5808#ifdef _SC_RE_DUP_MAX
5809 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5810#endif
5811#ifdef _SC_RTSIG_MAX
5812 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5813#endif
5814#ifdef _SC_SAVED_IDS
5815 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5816#endif
5817#ifdef _SC_SCHAR_MAX
5818 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5819#endif
5820#ifdef _SC_SCHAR_MIN
5821 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5822#endif
5823#ifdef _SC_SELECT
5824 {"SC_SELECT", _SC_SELECT},
5825#endif
5826#ifdef _SC_SEMAPHORES
5827 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5828#endif
5829#ifdef _SC_SEM_NSEMS_MAX
5830 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5831#endif
5832#ifdef _SC_SEM_VALUE_MAX
5833 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5834#endif
5835#ifdef _SC_SHARED_MEMORY_OBJECTS
5836 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5837#endif
5838#ifdef _SC_SHRT_MAX
5839 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5840#endif
5841#ifdef _SC_SHRT_MIN
5842 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5843#endif
5844#ifdef _SC_SIGQUEUE_MAX
5845 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5846#endif
5847#ifdef _SC_SIGRT_MAX
5848 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5849#endif
5850#ifdef _SC_SIGRT_MIN
5851 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5852#endif
Fred Draked86ed291999-12-15 15:34:33 +00005853#ifdef _SC_SOFTPOWER
5854 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5855#endif
Fred Drakec9680921999-12-13 16:37:25 +00005856#ifdef _SC_SPLIT_CACHE
5857 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5858#endif
5859#ifdef _SC_SSIZE_MAX
5860 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5861#endif
5862#ifdef _SC_STACK_PROT
5863 {"SC_STACK_PROT", _SC_STACK_PROT},
5864#endif
5865#ifdef _SC_STREAM_MAX
5866 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5867#endif
5868#ifdef _SC_SYNCHRONIZED_IO
5869 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5870#endif
5871#ifdef _SC_THREADS
5872 {"SC_THREADS", _SC_THREADS},
5873#endif
5874#ifdef _SC_THREAD_ATTR_STACKADDR
5875 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5876#endif
5877#ifdef _SC_THREAD_ATTR_STACKSIZE
5878 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5879#endif
5880#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5881 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5882#endif
5883#ifdef _SC_THREAD_KEYS_MAX
5884 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5885#endif
5886#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5887 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5888#endif
5889#ifdef _SC_THREAD_PRIO_INHERIT
5890 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5891#endif
5892#ifdef _SC_THREAD_PRIO_PROTECT
5893 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5894#endif
5895#ifdef _SC_THREAD_PROCESS_SHARED
5896 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5897#endif
5898#ifdef _SC_THREAD_SAFE_FUNCTIONS
5899 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5900#endif
5901#ifdef _SC_THREAD_STACK_MIN
5902 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5903#endif
5904#ifdef _SC_THREAD_THREADS_MAX
5905 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5906#endif
5907#ifdef _SC_TIMERS
5908 {"SC_TIMERS", _SC_TIMERS},
5909#endif
5910#ifdef _SC_TIMER_MAX
5911 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5912#endif
5913#ifdef _SC_TTY_NAME_MAX
5914 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5915#endif
5916#ifdef _SC_TZNAME_MAX
5917 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5918#endif
5919#ifdef _SC_T_IOV_MAX
5920 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5921#endif
5922#ifdef _SC_UCHAR_MAX
5923 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5924#endif
5925#ifdef _SC_UINT_MAX
5926 {"SC_UINT_MAX", _SC_UINT_MAX},
5927#endif
5928#ifdef _SC_UIO_MAXIOV
5929 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5930#endif
5931#ifdef _SC_ULONG_MAX
5932 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5933#endif
5934#ifdef _SC_USHRT_MAX
5935 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5936#endif
5937#ifdef _SC_VERSION
5938 {"SC_VERSION", _SC_VERSION},
5939#endif
5940#ifdef _SC_WORD_BIT
5941 {"SC_WORD_BIT", _SC_WORD_BIT},
5942#endif
5943#ifdef _SC_XBS5_ILP32_OFF32
5944 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5945#endif
5946#ifdef _SC_XBS5_ILP32_OFFBIG
5947 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5948#endif
5949#ifdef _SC_XBS5_LP64_OFF64
5950 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5951#endif
5952#ifdef _SC_XBS5_LPBIG_OFFBIG
5953 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5954#endif
5955#ifdef _SC_XOPEN_CRYPT
5956 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5957#endif
5958#ifdef _SC_XOPEN_ENH_I18N
5959 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5960#endif
5961#ifdef _SC_XOPEN_LEGACY
5962 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5963#endif
5964#ifdef _SC_XOPEN_REALTIME
5965 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5966#endif
5967#ifdef _SC_XOPEN_REALTIME_THREADS
5968 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5969#endif
5970#ifdef _SC_XOPEN_SHM
5971 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5972#endif
5973#ifdef _SC_XOPEN_UNIX
5974 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5975#endif
5976#ifdef _SC_XOPEN_VERSION
5977 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5978#endif
5979#ifdef _SC_XOPEN_XCU_VERSION
5980 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5981#endif
5982#ifdef _SC_XOPEN_XPG2
5983 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5984#endif
5985#ifdef _SC_XOPEN_XPG3
5986 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5987#endif
5988#ifdef _SC_XOPEN_XPG4
5989 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5990#endif
5991};
5992
5993static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005994conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005995{
5996 return conv_confname(arg, valuep, posix_constants_sysconf,
5997 sizeof(posix_constants_sysconf)
5998 / sizeof(struct constdef));
5999}
6000
6001static char posix_sysconf__doc__[] = "\
6002sysconf(name) -> integer\n\
6003Return an integer-valued system configuration variable.";
6004
6005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006006posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006007{
6008 PyObject *result = NULL;
6009 int name;
6010
6011 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6012 int value;
6013
6014 errno = 0;
6015 value = sysconf(name);
6016 if (value == -1 && errno != 0)
6017 posix_error();
6018 else
6019 result = PyInt_FromLong(value);
6020 }
6021 return result;
6022}
6023#endif
6024
6025
Fred Drakebec628d1999-12-15 18:31:10 +00006026/* This code is used to ensure that the tables of configuration value names
6027 * are in sorted order as required by conv_confname(), and also to build the
6028 * the exported dictionaries that are used to publish information about the
6029 * names available on the host platform.
6030 *
6031 * Sorting the table at runtime ensures that the table is properly ordered
6032 * when used, even for platforms we're not able to test on. It also makes
6033 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006034 */
Fred Drakebec628d1999-12-15 18:31:10 +00006035
6036static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006037cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006038{
6039 const struct constdef *c1 =
6040 (const struct constdef *) v1;
6041 const struct constdef *c2 =
6042 (const struct constdef *) v2;
6043
6044 return strcmp(c1->name, c2->name);
6045}
6046
6047static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006048setup_confname_table(struct constdef *table, size_t tablesize,
6049 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00006050{
Fred Drakebec628d1999-12-15 18:31:10 +00006051 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006052 size_t i;
6053 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00006054
6055 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6056 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006057 if (d == NULL)
6058 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006059
Barry Warsaw3155db32000-04-13 15:20:40 +00006060 for (i=0; i < tablesize; ++i) {
6061 PyObject *o = PyInt_FromLong(table[i].value);
6062 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6063 Py_XDECREF(o);
6064 Py_DECREF(d);
6065 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006066 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006067 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006068 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006069 status = PyDict_SetItemString(moddict, tablename, d);
6070 Py_DECREF(d);
6071 return status;
Fred Draked86ed291999-12-15 15:34:33 +00006072}
6073
Fred Drakebec628d1999-12-15 18:31:10 +00006074/* Return -1 on failure, 0 on success. */
6075static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006076setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00006077{
6078#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006079 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006080 sizeof(posix_constants_pathconf)
6081 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006082 "pathconf_names", moddict))
6083 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006084#endif
6085#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006086 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006087 sizeof(posix_constants_confstr)
6088 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006089 "confstr_names", moddict))
6090 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006091#endif
6092#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006093 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006094 sizeof(posix_constants_sysconf)
6095 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00006096 "sysconf_names", moddict))
6097 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006098#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006099 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006100}
Fred Draked86ed291999-12-15 15:34:33 +00006101
6102
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006103static char posix_abort__doc__[] = "\
6104abort() -> does not return!\n\
6105Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
6106in the hardest way possible on the hosting operating system.";
6107
6108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006109posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006110{
6111 if (!PyArg_ParseTuple(args, ":abort"))
6112 return NULL;
6113 abort();
6114 /*NOTREACHED*/
6115 Py_FatalError("abort() called from Python code didn't abort!");
6116 return NULL;
6117}
Fred Drakebec628d1999-12-15 18:31:10 +00006118
Tim Petersf58a7aa2000-09-22 10:05:54 +00006119#ifdef MS_WIN32
6120static char win32_startfile__doc__[] = "\
6121startfile(filepath) - Start a file with its associated application.\n\
6122\n\
6123This acts like double-clicking the file in Explorer, or giving the file\n\
6124name as an argument to the DOS \"start\" command: the file is opened\n\
6125with whatever application (if any) its extension is associated.\n\
6126\n\
6127startfile returns as soon as the associated application is launched.\n\
6128There is no option to wait for the application to close, and no way\n\
6129to retrieve the application's exit status.\n\
6130\n\
6131The filepath is relative to the current directory. If you want to use\n\
6132an absolute path, make sure the first character is not a slash (\"/\");\n\
6133the underlying Win32 ShellExecute function doesn't work if it is.";
6134
6135static PyObject *
6136win32_startfile(PyObject *self, PyObject *args)
6137{
6138 char *filepath;
6139 HINSTANCE rc;
6140 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6141 return NULL;
6142 Py_BEGIN_ALLOW_THREADS
6143 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6144 Py_END_ALLOW_THREADS
6145 if (rc <= (HINSTANCE)32)
6146 return win32_error("startfile", filepath);
6147 Py_INCREF(Py_None);
6148 return Py_None;
6149}
6150#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006151
6152static PyMethodDef posix_methods[] = {
6153 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6154#ifdef HAVE_TTYNAME
6155 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6156#endif
6157 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6158 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006159#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006160 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006161#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006162#ifdef HAVE_CHROOT
6163 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6164#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006165#ifdef HAVE_CTERMID
6166 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6167#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006168#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006169 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006170#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006171#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006172 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006173#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006174 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6175 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6176 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006177#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006178 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006179#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006180#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006181 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006182#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006183 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6184 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6185 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006186#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006187 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006188#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006189#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006190 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006191#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006192 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006193#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006194 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006195#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006196 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6197 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6198 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006199#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006200 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006201#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006202 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006203#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006204 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6205 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006206#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006207#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006208 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6209 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006210#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006211#ifdef HAVE_FORK1
6212 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6213#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006214#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006215 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006216#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006217#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006218 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006219#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006220#ifdef HAVE_FORKPTY
6221 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6222#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006223#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006224 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006225#endif /* HAVE_GETEGID */
6226#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006227 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006228#endif /* HAVE_GETEUID */
6229#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006230 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006231#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006232#ifdef HAVE_GETGROUPS
6233 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6234#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006235 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006236#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006237 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006238#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006239#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006240 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006241#endif /* HAVE_GETPPID */
6242#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006243 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006244#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006245#ifdef HAVE_GETLOGIN
6246 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6247#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006248#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006249 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006250#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006251#ifdef HAVE_KILLPG
6252 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6253#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006254#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006255 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006256#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006257#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006258 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006259#ifdef MS_WIN32
6260 {"popen2", win32_popen2, METH_VARARGS},
6261 {"popen3", win32_popen3, METH_VARARGS},
6262 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006263 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006264#else
6265#if defined(PYOS_OS2) && defined(PYCC_GCC)
6266 {"popen2", os2emx_popen2, METH_VARARGS},
6267 {"popen3", os2emx_popen3, METH_VARARGS},
6268 {"popen4", os2emx_popen4, METH_VARARGS},
6269#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006270#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006271#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006272#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006273 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006274#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006275#ifdef HAVE_SETEUID
6276 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6277#endif /* HAVE_SETEUID */
6278#ifdef HAVE_SETEGID
6279 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6280#endif /* HAVE_SETEGID */
6281#ifdef HAVE_SETREUID
6282 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6283#endif /* HAVE_SETREUID */
6284#ifdef HAVE_SETREGID
6285 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6286#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006287#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006288 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006289#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006290#ifdef HAVE_SETGROUPS
6291 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6292#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006293#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006294 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006295#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006296#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006297 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006298#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006299#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006300 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006301#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006302#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006303 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006304#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006305#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006306 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006307#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006308#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006309 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006310#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006311#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006312 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006313#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006314 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6315 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6316 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6317 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6318 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6319 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6320 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6321 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6322 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006323 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006324#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006325 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006326#endif
6327#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006328 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006329#endif
6330#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006331 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006332#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006333#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006334 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006335#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006336#ifdef HAVE_UNSETENV
6337 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6338#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006339#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006340 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006341#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006342#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006343 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006344#endif
6345#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006346 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006347#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006348#ifdef HAVE_SYS_WAIT_H
6349#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006350 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006351#endif /* WIFSTOPPED */
6352#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006353 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006354#endif /* WIFSIGNALED */
6355#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006356 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006357#endif /* WIFEXITED */
6358#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006359 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006360#endif /* WEXITSTATUS */
6361#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006362 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006363#endif /* WTERMSIG */
6364#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006366#endif /* WSTOPSIG */
6367#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006368#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006369 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006370#endif
6371#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006372 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006373#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006374#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006375 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6376#endif
6377#ifdef HAVE_TEMPNAM
6378 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6379#endif
6380#ifdef HAVE_TMPNAM
6381 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6382#endif
Fred Drakec9680921999-12-13 16:37:25 +00006383#ifdef HAVE_CONFSTR
6384 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6385#endif
6386#ifdef HAVE_SYSCONF
6387 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6388#endif
6389#ifdef HAVE_FPATHCONF
6390 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6391#endif
6392#ifdef HAVE_PATHCONF
6393 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6394#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006395 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00006396#ifdef MS_WIN32
6397 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6398#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006399 {NULL, NULL} /* Sentinel */
6400};
6401
6402
Barry Warsaw4a342091996-12-19 23:50:02 +00006403static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006404ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006405{
6406 PyObject* v = PyInt_FromLong(value);
6407 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
6408 return -1; /* triggers fatal error */
6409
6410 Py_DECREF(v);
6411 return 0;
6412}
6413
Guido van Rossumd48f2521997-12-05 22:19:34 +00006414#if defined(PYOS_OS2)
6415/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
6416static int insertvalues(PyObject *d)
6417{
6418 APIRET rc;
6419 ULONG values[QSV_MAX+1];
6420 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006421 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006422
6423 Py_BEGIN_ALLOW_THREADS
6424 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6425 Py_END_ALLOW_THREADS
6426
6427 if (rc != NO_ERROR) {
6428 os2_error(rc);
6429 return -1;
6430 }
6431
6432 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6433 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
6434 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6435 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6436 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6437 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
6438 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
6439
6440 switch (values[QSV_VERSION_MINOR]) {
6441 case 0: ver = "2.00"; break;
6442 case 10: ver = "2.10"; break;
6443 case 11: ver = "2.11"; break;
6444 case 30: ver = "3.00"; break;
6445 case 40: ver = "4.00"; break;
6446 case 50: ver = "5.00"; break;
6447 default:
Tim Peters885d4572001-11-28 20:27:42 +00006448 PyOS_snprintf(tmp, sizeof(tmp),
6449 "%d-%d", values[QSV_VERSION_MAJOR],
6450 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006451 ver = &tmp[0];
6452 }
6453
6454 /* Add Indicator of the Version of the Operating System */
6455 v = PyString_FromString(ver);
6456 if (!v || PyDict_SetItemString(d, "version", v) < 0)
6457 return -1;
6458 Py_DECREF(v);
6459
6460 /* Add Indicator of Which Drive was Used to Boot the System */
6461 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6462 tmp[1] = ':';
6463 tmp[2] = '\0';
6464
6465 v = PyString_FromString(tmp);
6466 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
6467 return -1;
6468 Py_DECREF(v);
6469
6470 return 0;
6471}
6472#endif
6473
Barry Warsaw4a342091996-12-19 23:50:02 +00006474static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006475all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006476{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006477#ifdef F_OK
6478 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006479#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006480#ifdef R_OK
6481 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006482#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006483#ifdef W_OK
6484 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006485#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006486#ifdef X_OK
6487 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006488#endif
Fred Drakec9680921999-12-13 16:37:25 +00006489#ifdef NGROUPS_MAX
6490 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6491#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006492#ifdef TMP_MAX
6493 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6494#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006495#ifdef WNOHANG
6496 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006497#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006498#ifdef O_RDONLY
6499 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6500#endif
6501#ifdef O_WRONLY
6502 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6503#endif
6504#ifdef O_RDWR
6505 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6506#endif
6507#ifdef O_NDELAY
6508 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6509#endif
6510#ifdef O_NONBLOCK
6511 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6512#endif
6513#ifdef O_APPEND
6514 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6515#endif
6516#ifdef O_DSYNC
6517 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6518#endif
6519#ifdef O_RSYNC
6520 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6521#endif
6522#ifdef O_SYNC
6523 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6524#endif
6525#ifdef O_NOCTTY
6526 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6527#endif
6528#ifdef O_CREAT
6529 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6530#endif
6531#ifdef O_EXCL
6532 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6533#endif
6534#ifdef O_TRUNC
6535 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6536#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006537#ifdef O_BINARY
6538 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6539#endif
6540#ifdef O_TEXT
6541 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6542#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006543#ifdef O_LARGEFILE
6544 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6545#endif
6546
Tim Peters5aa91602002-01-30 05:46:57 +00006547/* MS Windows */
6548#ifdef O_NOINHERIT
6549 /* Don't inherit in child processes. */
6550 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6551#endif
6552#ifdef _O_SHORT_LIVED
6553 /* Optimize for short life (keep in memory). */
6554 /* MS forgot to define this one with a non-underscore form too. */
6555 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6556#endif
6557#ifdef O_TEMPORARY
6558 /* Automatically delete when last handle is closed. */
6559 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6560#endif
6561#ifdef O_RANDOM
6562 /* Optimize for random access. */
6563 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6564#endif
6565#ifdef O_SEQUENTIAL
6566 /* Optimize for sequential access. */
6567 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6568#endif
6569
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006570/* GNU extensions. */
6571#ifdef O_DIRECT
6572 /* Direct disk access. */
6573 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6574#endif
6575#ifdef O_DIRECTORY
6576 /* Must be a directory. */
6577 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6578#endif
6579#ifdef O_NOFOLLOW
6580 /* Do not follow links. */
6581 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6582#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006583
Guido van Rossum246bc171999-02-01 23:54:31 +00006584#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006585#if defined(PYOS_OS2) && defined(PYCC_GCC)
6586 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6587 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6588 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6589 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6590 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6591 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6592 if (ins(d, "P_PM", (long)P_PM)) return -1;
6593 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6594 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6595 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6596 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6597 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6598 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6599 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6600 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6601 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6602 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6603 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6604 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6605 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6606#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006607 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6608 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6609 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6610 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6611 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006612#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006613#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006614
Guido van Rossumd48f2521997-12-05 22:19:34 +00006615#if defined(PYOS_OS2)
6616 if (insertvalues(d)) return -1;
6617#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006618 return 0;
6619}
6620
6621
Tim Peters5aa91602002-01-30 05:46:57 +00006622#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006623#define INITFUNC initnt
6624#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006625
6626#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006627#define INITFUNC initos2
6628#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006629
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006630#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006631#define INITFUNC initposix
6632#define MODNAME "posix"
6633#endif
6634
Guido van Rossum3886bb61998-12-04 18:50:17 +00006635DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006636INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006637{
Barry Warsaw53699e91996-12-10 23:23:01 +00006638 PyObject *m, *d, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006639
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006640 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006641 posix_methods,
6642 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006643 (PyObject *)NULL,
6644 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00006645 d = PyModule_GetDict(m);
Tim Peters5aa91602002-01-30 05:46:57 +00006646
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006647 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006648 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00006649 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006650 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006651 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006652
Barry Warsaw4a342091996-12-19 23:50:02 +00006653 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00006654 return;
6655
Fred Drakebec628d1999-12-15 18:31:10 +00006656 if (setup_confname_tables(d))
6657 return;
6658
Barry Warsawca74da41999-02-09 19:31:45 +00006659 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006660
Guido van Rossumb3d39562000-01-31 18:41:26 +00006661#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006662 if (posix_putenv_garbage == NULL)
6663 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006664#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006665
Guido van Rossum14648392001-12-08 18:02:58 +00006666 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006667 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
6668 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
6669
Guido van Rossum14648392001-12-08 18:02:58 +00006670 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006671 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Guido van Rossumbb2501f2001-12-27 16:23:28 +00006672 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006673}