blob: b9aa28aa5031e5d4c1a88ba5d268c37a6afedbd5 [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 *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000463posix_fildes(PyObject *fdobj, int (*func)(int))
464{
465 int fd;
466 int res;
467 fd = PyObject_AsFileDescriptor(fdobj);
468 if (fd < 0)
469 return NULL;
470 Py_BEGIN_ALLOW_THREADS
471 res = (*func)(fd);
472 Py_END_ALLOW_THREADS
473 if (res < 0)
474 return posix_error();
475 Py_INCREF(Py_None);
476 return Py_None;
477}
Guido van Rossum21142a01999-01-08 21:05:37 +0000478
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
Fred Drake4d1e64b2002-04-15 19:40:07 +0000826#ifdef HAVE_FCHDIR
827static char posix_fchdir__doc__[] =
828"fchdir(fildes) -> None\n\
829Change to the directory of the given file descriptor. fildes must be\n\
830opened on a directory, not a file.";
831
832static PyObject *
833posix_fchdir(PyObject *self, PyObject *fdobj)
834{
835 return posix_fildes(fdobj, fchdir);
836}
837#endif /* HAVE_FCHDIR */
838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000839
840static char posix_chmod__doc__[] =
841"chmod(path, mode) -> None\n\
842Change the access permissions of a file.";
843
Barry Warsaw53699e91996-12-10 23:23:01 +0000844static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000845posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846{
Mark Hammondef8b6542001-05-13 08:04:26 +0000847 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000848 int i;
849 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000850 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000851 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000852 return NULL;
853 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000854 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000855 Py_END_ALLOW_THREADS
856 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000857 return posix_error_with_allocated_filename(path);
858 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000859 Py_INCREF(Py_None);
860 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861}
862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000863
Martin v. Löwis244edc82001-10-04 22:44:26 +0000864#ifdef HAVE_CHROOT
Tim Peters5aa91602002-01-30 05:46:57 +0000865static char posix_chroot__doc__[] =
Martin v. Löwis244edc82001-10-04 22:44:26 +0000866"chroot(path) -> None\n\
867Change root directory to path.";
868
869static PyObject *
870posix_chroot(PyObject *self, PyObject *args)
871{
872 return posix_1str(args, "et:chroot", chroot);
873}
874#endif
875
Guido van Rossum21142a01999-01-08 21:05:37 +0000876#ifdef HAVE_FSYNC
877static char posix_fsync__doc__[] =
878"fsync(fildes) -> None\n\
879force write of file with filedescriptor to disk.";
880
881static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000882posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000883{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000884 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000885}
886#endif /* HAVE_FSYNC */
887
888#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000889
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000890#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000891extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
892#endif
893
Guido van Rossum21142a01999-01-08 21:05:37 +0000894static char posix_fdatasync__doc__[] =
895"fdatasync(fildes) -> None\n\
896force write of file with filedescriptor to disk.\n\
897 does not force update of metadata.";
898
899static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000900posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000901{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000902 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000903}
904#endif /* HAVE_FDATASYNC */
905
906
Fredrik Lundh10723342000-07-10 16:38:09 +0000907#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000908static char posix_chown__doc__[] =
909"chown(path, uid, gid) -> None\n\
910Change the owner and group id of path to the numeric uid and gid.";
911
Barry Warsaw53699e91996-12-10 23:23:01 +0000912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000913posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000914{
Mark Hammondef8b6542001-05-13 08:04:26 +0000915 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000916 int uid, gid;
917 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000918 if (!PyArg_ParseTuple(args, "etii:chown",
919 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000920 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000921 return NULL;
922 Py_BEGIN_ALLOW_THREADS
923 res = chown(path, (uid_t) uid, (gid_t) gid);
924 Py_END_ALLOW_THREADS
925 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000926 return posix_error_with_allocated_filename(path);
927 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000928 Py_INCREF(Py_None);
929 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000930}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000931#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000933
Guido van Rossum36bc6801995-06-14 22:54:23 +0000934#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000935static char posix_getcwd__doc__[] =
936"getcwd() -> path\n\
937Return a string representing the current working directory.";
938
Barry Warsaw53699e91996-12-10 23:23:01 +0000939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000940posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000941{
942 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000943 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000944 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000945 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000946 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000947#if defined(PYOS_OS2) && defined(PYCC_GCC)
948 res = _getcwd2(buf, sizeof buf);
949#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000950 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000951#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000952 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000953 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000955 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000957#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000959
Guido van Rossumb6775db1994-08-01 11:34:53 +0000960#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000961static char posix_link__doc__[] =
962"link(src, dst) -> None\n\
963Create a hard link to a file.";
964
Barry Warsaw53699e91996-12-10 23:23:01 +0000965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000966posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000967{
Mark Hammondef8b6542001-05-13 08:04:26 +0000968 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000969}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000970#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000972
973static char posix_listdir__doc__[] =
974"listdir(path) -> list_of_strings\n\
975Return a list containing the names of the entries in the directory.\n\
976\n\
977 path: path of directory to list\n\
978\n\
979The list is in arbitrary order. It does not include the special\n\
980entries '.' and '..' even if they are present in the directory.";
981
Barry Warsaw53699e91996-12-10 23:23:01 +0000982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000983posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000984{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000985 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000986 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000987#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000988
Barry Warsaw53699e91996-12-10 23:23:01 +0000989 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000990 HANDLE hFindFile;
991 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000992 /* MAX_PATH characters could mean a bigger encoded string */
993 char namebuf[MAX_PATH*2+5];
994 char *bufptr = namebuf;
995 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000996
Tim Peters5aa91602002-01-30 05:46:57 +0000997 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +0000998 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000999 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001000 if (len > 0) {
1001 char ch = namebuf[len-1];
1002 if (ch != SEP && ch != ALTSEP && ch != ':')
1003 namebuf[len++] = '/';
1004 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001005 strcpy(namebuf + len, "*.*");
1006
Barry Warsaw53699e91996-12-10 23:23:01 +00001007 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001008 return NULL;
1009
1010 hFindFile = FindFirstFile(namebuf, &FileData);
1011 if (hFindFile == INVALID_HANDLE_VALUE) {
1012 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001013 if (errno == ERROR_FILE_NOT_FOUND)
1014 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001015 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001016 }
1017 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001018 if (FileData.cFileName[0] == '.' &&
1019 (FileData.cFileName[1] == '\0' ||
1020 FileData.cFileName[1] == '.' &&
1021 FileData.cFileName[2] == '\0'))
1022 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001023 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001024 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001025 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001026 d = NULL;
1027 break;
1028 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001029 if (PyList_Append(d, v) != 0) {
1030 Py_DECREF(v);
1031 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001032 d = NULL;
1033 break;
1034 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001035 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001036 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1037
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001038 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001039 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001040
1041 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001042
Tim Peters0bb44a42000-09-15 07:44:49 +00001043#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001044
1045#ifndef MAX_PATH
1046#define MAX_PATH 250
1047#endif
1048 char *name, *pt;
1049 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001050 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001051 char namebuf[MAX_PATH+5];
1052 struct _find_t ep;
1053
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001054 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001055 return NULL;
1056 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001057 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001058 return NULL;
1059 }
1060 strcpy(namebuf, name);
1061 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001062 if (*pt == ALTSEP)
1063 *pt = SEP;
1064 if (namebuf[len-1] != SEP)
1065 namebuf[len++] = SEP;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001066 strcpy(namebuf + len, "*.*");
1067
Barry Warsaw53699e91996-12-10 23:23:01 +00001068 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001069 return NULL;
1070
1071 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001072 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1073 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001074 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001075 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001076 }
1077 do {
1078 if (ep.name[0] == '.' &&
1079 (ep.name[1] == '\0' ||
1080 ep.name[1] == '.' &&
1081 ep.name[2] == '\0'))
1082 continue;
1083 strcpy(namebuf, ep.name);
1084 for (pt = namebuf; *pt; pt++)
1085 if (isupper(*pt))
1086 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001087 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001088 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001089 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001090 d = NULL;
1091 break;
1092 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001093 if (PyList_Append(d, v) != 0) {
1094 Py_DECREF(v);
1095 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001096 d = NULL;
1097 break;
1098 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001099 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001100 } while (_dos_findnext(&ep) == 0);
1101
1102 return d;
1103
Tim Peters0bb44a42000-09-15 07:44:49 +00001104#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001105
1106#ifndef MAX_PATH
1107#define MAX_PATH CCHMAXPATH
1108#endif
1109 char *name, *pt;
1110 int len;
1111 PyObject *d, *v;
1112 char namebuf[MAX_PATH+5];
1113 HDIR hdir = 1;
1114 ULONG srchcnt = 1;
1115 FILEFINDBUF3 ep;
1116 APIRET rc;
1117
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001118 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001119 return NULL;
1120 if (len >= MAX_PATH) {
1121 PyErr_SetString(PyExc_ValueError, "path too long");
1122 return NULL;
1123 }
1124 strcpy(namebuf, name);
1125 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001126 if (*pt == ALTSEP)
1127 *pt = SEP;
1128 if (namebuf[len-1] != SEP)
1129 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001130 strcpy(namebuf + len, "*.*");
1131
1132 if ((d = PyList_New(0)) == NULL)
1133 return NULL;
1134
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001135 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1136 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001137 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001138 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1139 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1140 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001141
1142 if (rc != NO_ERROR) {
1143 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001144 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001145 }
1146
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001147 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001148 do {
1149 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001150 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001151 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001152
1153 strcpy(namebuf, ep.achName);
1154
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001155 /* Leave Case of Name Alone -- In Native Form */
1156 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001157
1158 v = PyString_FromString(namebuf);
1159 if (v == NULL) {
1160 Py_DECREF(d);
1161 d = NULL;
1162 break;
1163 }
1164 if (PyList_Append(d, v) != 0) {
1165 Py_DECREF(v);
1166 Py_DECREF(d);
1167 d = NULL;
1168 break;
1169 }
1170 Py_DECREF(v);
1171 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1172 }
1173
1174 return d;
1175#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001176
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001177 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001178 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001179 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001180 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001181 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001183 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001184 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001185 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001186 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001187 closedir(dirp);
1188 return NULL;
1189 }
1190 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001191 if (ep->d_name[0] == '.' &&
1192 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001193 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001194 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001195 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001196 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001197 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001198 d = NULL;
1199 break;
1200 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001201 if (PyList_Append(d, v) != 0) {
1202 Py_DECREF(v);
1203 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001204 d = NULL;
1205 break;
1206 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001207 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001208 }
1209 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001210
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001212
Tim Peters0bb44a42000-09-15 07:44:49 +00001213#endif /* which OS */
1214} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215
Mark Hammondef8b6542001-05-13 08:04:26 +00001216#ifdef MS_WIN32
1217/* A helper function for abspath on win32 */
1218static PyObject *
1219posix__getfullpathname(PyObject *self, PyObject *args)
1220{
1221 /* assume encoded strings wont more than double no of chars */
1222 char inbuf[MAX_PATH*2];
1223 char *inbufp = inbuf;
1224 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1225 char outbuf[MAX_PATH*2];
1226 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001227 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1228 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001229 &insize))
1230 return NULL;
1231 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1232 outbuf, &temp))
1233 return win32_error("GetFullPathName", inbuf);
1234 return PyString_FromString(outbuf);
1235} /* end of posix__getfullpathname */
1236#endif /* MS_WIN32 */
1237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001238static char posix_mkdir__doc__[] =
1239"mkdir(path [, mode=0777]) -> None\n\
1240Create a directory.";
1241
Barry Warsaw53699e91996-12-10 23:23:01 +00001242static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001243posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001244{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001245 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001246 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001247 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001248 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001249 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001250 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001251 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001252#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001253 res = mkdir(path);
1254#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001255 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001256#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001257 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001258 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001259 return posix_error_with_allocated_filename(path);
1260 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001261 Py_INCREF(Py_None);
1262 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001263}
1264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001265
Guido van Rossumb6775db1994-08-01 11:34:53 +00001266#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001267#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1268#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1269#include <sys/resource.h>
1270#endif
1271#endif
1272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001273static char posix_nice__doc__[] =
1274"nice(inc) -> new_priority\n\
1275Decrease the priority of process and return new priority.";
1276
Barry Warsaw53699e91996-12-10 23:23:01 +00001277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001278posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001279{
1280 int increment, value;
1281
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001282 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001283 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001284
1285 /* There are two flavours of 'nice': one that returns the new
1286 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001287 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1288 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001289
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001290 If we are of the nice family that returns the new priority, we
1291 need to clear errno before the call, and check if errno is filled
1292 before calling posix_error() on a returnvalue of -1, because the
1293 -1 may be the actual new priority! */
1294
1295 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001296 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001297#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001298 if (value == 0)
1299 value = getpriority(PRIO_PROCESS, 0);
1300#endif
1301 if (value == -1 && errno != 0)
1302 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001303 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001304 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001305}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001306#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001308
1309static char posix_rename__doc__[] =
1310"rename(old, new) -> None\n\
1311Rename a file or directory.";
1312
Barry Warsaw53699e91996-12-10 23:23:01 +00001313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001314posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001315{
Mark Hammondef8b6542001-05-13 08:04:26 +00001316 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001317}
1318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001319
1320static char posix_rmdir__doc__[] =
1321"rmdir(path) -> None\n\
1322Remove a directory.";
1323
Barry Warsaw53699e91996-12-10 23:23:01 +00001324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001325posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326{
Mark Hammondef8b6542001-05-13 08:04:26 +00001327 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001328}
1329
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001330
1331static char posix_stat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00001332"stat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
1333 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001334Perform a stat system call on the given path.";
1335
Barry Warsaw53699e91996-12-10 23:23:01 +00001336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001337posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001338{
Mark Hammondef8b6542001-05-13 08:04:26 +00001339 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001340}
1341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001342
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001343#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001344static char posix_system__doc__[] =
1345"system(command) -> exit_status\n\
1346Execute the command (a string) in a subshell.";
1347
Barry Warsaw53699e91996-12-10 23:23:01 +00001348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001349posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001351 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001352 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001353 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001354 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001355 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001356 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001357 Py_END_ALLOW_THREADS
1358 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001359}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001360#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001361
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001362
1363static char posix_umask__doc__[] =
1364"umask(new_mask) -> old_mask\n\
1365Set the current numeric umask and return the previous umask.";
1366
Barry Warsaw53699e91996-12-10 23:23:01 +00001367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001368posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001369{
1370 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001371 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001372 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001373 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001374 if (i < 0)
1375 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001376 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001377}
1378
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001379
1380static char posix_unlink__doc__[] =
1381"unlink(path) -> None\n\
1382Remove a file (same as remove(path)).";
1383
1384static char posix_remove__doc__[] =
1385"remove(path) -> None\n\
1386Remove a file (same as unlink(path)).";
1387
Barry Warsaw53699e91996-12-10 23:23:01 +00001388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001389posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390{
Mark Hammondef8b6542001-05-13 08:04:26 +00001391 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392}
1393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001394
Guido van Rossumb6775db1994-08-01 11:34:53 +00001395#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001396static char posix_uname__doc__[] =
1397"uname() -> (sysname, nodename, release, version, machine)\n\
1398Return a tuple identifying the current operating system.";
1399
Barry Warsaw53699e91996-12-10 23:23:01 +00001400static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001401posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001402{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001403 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001404 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001405 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001406 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001407 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001408 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001409 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001410 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001411 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001412 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001413 u.sysname,
1414 u.nodename,
1415 u.release,
1416 u.version,
1417 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001418}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001419#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001420
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001421
1422static char posix_utime__doc__[] =
1423"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001424utime(path, None) -> None\n\
1425Set the access and modified time of the file to the given values. If the\n\
1426second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001427
Barry Warsaw53699e91996-12-10 23:23:01 +00001428static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001429posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001430{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001431 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001432 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001433 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001434 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001435
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001436/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001437#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001438 struct utimbuf buf;
1439#define ATIME buf.actime
1440#define MTIME buf.modtime
1441#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001442#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001443 time_t buf[2];
1444#define ATIME buf[0]
1445#define MTIME buf[1]
1446#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001447#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001448
Barry Warsaw3cef8562000-05-01 16:17:24 +00001449 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001450 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001451 if (arg == Py_None) {
1452 /* optional time values not given */
1453 Py_BEGIN_ALLOW_THREADS
1454 res = utime(path, NULL);
1455 Py_END_ALLOW_THREADS
1456 }
1457 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1458 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001459 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001460 return NULL;
1461 }
1462 else {
1463 ATIME = atime;
1464 MTIME = mtime;
1465 Py_BEGIN_ALLOW_THREADS
1466 res = utime(path, UTIME_ARG);
1467 Py_END_ALLOW_THREADS
1468 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001469 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001470 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001471 Py_INCREF(Py_None);
1472 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001473#undef UTIME_ARG
1474#undef ATIME
1475#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001476}
1477
Guido van Rossum85e3b011991-06-03 12:42:10 +00001478
Guido van Rossum3b066191991-06-04 19:40:25 +00001479/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001480
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001481static char posix__exit__doc__[] =
1482"_exit(status)\n\
1483Exit to the system with specified status, without normal exit processing.";
1484
Barry Warsaw53699e91996-12-10 23:23:01 +00001485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001486posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001487{
1488 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001489 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001490 return NULL;
1491 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001492 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001493}
1494
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001495
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001496#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001497static char posix_execv__doc__[] =
1498"execv(path, args)\n\
1499Execute an executable path with arguments, replacing current process.\n\
1500\n\
1501 path: path of executable file\n\
1502 args: tuple or list of strings";
1503
Barry Warsaw53699e91996-12-10 23:23:01 +00001504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001505posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001506{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001507 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001508 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001509 char **argvlist;
1510 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001511 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001512
Guido van Rossum89b33251993-10-22 14:26:06 +00001513 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001514 argv is a list or tuple of strings. */
1515
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001516 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001517 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001518 if (PyList_Check(argv)) {
1519 argc = PyList_Size(argv);
1520 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001521 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001522 else if (PyTuple_Check(argv)) {
1523 argc = PyTuple_Size(argv);
1524 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001525 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001526 else {
Fred Drake661ea262000-10-24 19:57:45 +00001527 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001528 return NULL;
1529 }
1530
1531 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001532 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001533 return NULL;
1534 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001535
Barry Warsaw53699e91996-12-10 23:23:01 +00001536 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001537 if (argvlist == NULL)
1538 return NULL;
1539 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001540 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1541 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001542 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001543 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001544 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001545
Guido van Rossum85e3b011991-06-03 12:42:10 +00001546 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001547 }
1548 argvlist[argc] = NULL;
1549
Guido van Rossumb6775db1994-08-01 11:34:53 +00001550#ifdef BAD_EXEC_PROTOTYPES
1551 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001552#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001553 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001554#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001555
Guido van Rossum85e3b011991-06-03 12:42:10 +00001556 /* If we get here it's definitely an error */
1557
Barry Warsaw53699e91996-12-10 23:23:01 +00001558 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001559 return posix_error();
1560}
1561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001562
1563static char posix_execve__doc__[] =
1564"execve(path, args, env)\n\
1565Execute a path with arguments and environment, replacing current process.\n\
1566\n\
1567 path: path of executable file\n\
1568 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001569 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001570
Barry Warsaw53699e91996-12-10 23:23:01 +00001571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001572posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001573{
1574 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001575 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001576 char **argvlist;
1577 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001578 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001579 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001580 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001581
1582 /* execve has three arguments: (path, argv, env), where
1583 argv is a list or tuple of strings and env is a dictionary
1584 like posix.environ. */
1585
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001586 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001587 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001588 if (PyList_Check(argv)) {
1589 argc = PyList_Size(argv);
1590 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001591 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001592 else if (PyTuple_Check(argv)) {
1593 argc = PyTuple_Size(argv);
1594 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001595 }
1596 else {
Fred Drake661ea262000-10-24 19:57:45 +00001597 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001598 return NULL;
1599 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001600 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001601 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001602 return NULL;
1603 }
1604
Guido van Rossum50422b42000-04-26 20:34:28 +00001605 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001606 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001607 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001608 return NULL;
1609 }
1610
Barry Warsaw53699e91996-12-10 23:23:01 +00001611 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001612 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001613 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001614 return NULL;
1615 }
1616 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001617 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001618 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001619 &argvlist[i]))
1620 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001621 goto fail_1;
1622 }
1623 }
1624 argvlist[argc] = NULL;
1625
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001626 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001627 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001628 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001629 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001630 goto fail_1;
1631 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001632 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001633 keys = PyMapping_Keys(env);
1634 vals = PyMapping_Values(env);
1635 if (!keys || !vals)
1636 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001637
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001638 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001639 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001640 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001641
1642 key = PyList_GetItem(keys, pos);
1643 val = PyList_GetItem(vals, pos);
1644 if (!key || !val)
1645 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001646
Fred Drake661ea262000-10-24 19:57:45 +00001647 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1648 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001649 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001650 goto fail_2;
1651 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001652
1653#if defined(PYOS_OS2)
1654 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1655 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1656#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001657 len = PyString_Size(key) + PyString_Size(val) + 2;
1658 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001659 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001660 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001661 goto fail_2;
1662 }
Tim Petersc8996f52001-12-03 20:41:00 +00001663 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001664 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001665#if defined(PYOS_OS2)
1666 }
1667#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001668 }
1669 envlist[envc] = 0;
1670
Guido van Rossumb6775db1994-08-01 11:34:53 +00001671
1672#ifdef BAD_EXEC_PROTOTYPES
1673 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001674#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001675 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001676#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001677
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001678 /* If we get here it's definitely an error */
1679
1680 (void) posix_error();
1681
1682 fail_2:
1683 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001684 PyMem_DEL(envlist[envc]);
1685 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001686 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001687 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001688 Py_XDECREF(vals);
1689 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001690 return NULL;
1691}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001692#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001693
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001694
Guido van Rossuma1065681999-01-25 23:20:23 +00001695#ifdef HAVE_SPAWNV
1696static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001697"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001698Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001699\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001700 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001701 path: path of executable file\n\
1702 args: tuple or list of strings";
1703
1704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001705posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001706{
1707 char *path;
1708 PyObject *argv;
1709 char **argvlist;
1710 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001711 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001712 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001713
1714 /* spawnv has three arguments: (mode, path, argv), where
1715 argv is a list or tuple of strings. */
1716
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001717 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001718 return NULL;
1719 if (PyList_Check(argv)) {
1720 argc = PyList_Size(argv);
1721 getitem = PyList_GetItem;
1722 }
1723 else if (PyTuple_Check(argv)) {
1724 argc = PyTuple_Size(argv);
1725 getitem = PyTuple_GetItem;
1726 }
1727 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001728 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001729 return NULL;
1730 }
1731
1732 argvlist = PyMem_NEW(char *, argc+1);
1733 if (argvlist == NULL)
1734 return NULL;
1735 for (i = 0; i < argc; i++) {
1736 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1737 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001738 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001739 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001740 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001741 }
1742 }
1743 argvlist[argc] = NULL;
1744
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001745#if defined(PYOS_OS2) && defined(PYCC_GCC)
1746 Py_BEGIN_ALLOW_THREADS
1747 spawnval = spawnv(mode, path, argvlist);
1748 Py_END_ALLOW_THREADS
1749#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001750 if (mode == _OLD_P_OVERLAY)
1751 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001752
Tim Peters25059d32001-12-07 20:35:43 +00001753 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001754 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001755 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001756#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001757
Guido van Rossuma1065681999-01-25 23:20:23 +00001758 PyMem_DEL(argvlist);
1759
Fred Drake699f3522000-06-29 21:12:41 +00001760 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001761 return posix_error();
1762 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001763#if SIZEOF_LONG == SIZEOF_VOID_P
1764 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001765#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001766 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001767#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001768}
1769
1770
1771static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001772"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001773Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001774\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001775 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001776 path: path of executable file\n\
1777 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001778 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001779
1780static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001781posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001782{
1783 char *path;
1784 PyObject *argv, *env;
1785 char **argvlist;
1786 char **envlist;
1787 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1788 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001789 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001790 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001791
1792 /* spawnve has four arguments: (mode, path, argv, env), where
1793 argv is a list or tuple of strings and env is a dictionary
1794 like posix.environ. */
1795
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001796 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001797 return NULL;
1798 if (PyList_Check(argv)) {
1799 argc = PyList_Size(argv);
1800 getitem = PyList_GetItem;
1801 }
1802 else if (PyTuple_Check(argv)) {
1803 argc = PyTuple_Size(argv);
1804 getitem = PyTuple_GetItem;
1805 }
1806 else {
Fred Drake661ea262000-10-24 19:57:45 +00001807 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001808 return NULL;
1809 }
1810 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001811 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001812 return NULL;
1813 }
1814
1815 argvlist = PyMem_NEW(char *, argc+1);
1816 if (argvlist == NULL) {
1817 PyErr_NoMemory();
1818 return NULL;
1819 }
1820 for (i = 0; i < argc; i++) {
1821 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001822 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001823 &argvlist[i]))
1824 {
1825 goto fail_1;
1826 }
1827 }
1828 argvlist[argc] = NULL;
1829
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001830 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001831 envlist = PyMem_NEW(char *, i + 1);
1832 if (envlist == NULL) {
1833 PyErr_NoMemory();
1834 goto fail_1;
1835 }
1836 envc = 0;
1837 keys = PyMapping_Keys(env);
1838 vals = PyMapping_Values(env);
1839 if (!keys || !vals)
1840 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001841
Guido van Rossuma1065681999-01-25 23:20:23 +00001842 for (pos = 0; pos < i; pos++) {
1843 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001844 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001845
1846 key = PyList_GetItem(keys, pos);
1847 val = PyList_GetItem(vals, pos);
1848 if (!key || !val)
1849 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001850
Fred Drake661ea262000-10-24 19:57:45 +00001851 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1852 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001853 {
1854 goto fail_2;
1855 }
Tim Petersc8996f52001-12-03 20:41:00 +00001856 len = PyString_Size(key) + PyString_Size(val) + 2;
1857 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001858 if (p == NULL) {
1859 PyErr_NoMemory();
1860 goto fail_2;
1861 }
Tim Petersc8996f52001-12-03 20:41:00 +00001862 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001863 envlist[envc++] = p;
1864 }
1865 envlist[envc] = 0;
1866
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001867#if defined(PYOS_OS2) && defined(PYCC_GCC)
1868 Py_BEGIN_ALLOW_THREADS
1869 spawnval = spawnve(mode, path, argvlist, envlist);
1870 Py_END_ALLOW_THREADS
1871#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001872 if (mode == _OLD_P_OVERLAY)
1873 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001874
1875 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001876 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001877 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001878#endif
Tim Peters25059d32001-12-07 20:35:43 +00001879
Fred Drake699f3522000-06-29 21:12:41 +00001880 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001881 (void) posix_error();
1882 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001883#if SIZEOF_LONG == SIZEOF_VOID_P
1884 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001885#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001886 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001887#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001888
1889 fail_2:
1890 while (--envc >= 0)
1891 PyMem_DEL(envlist[envc]);
1892 PyMem_DEL(envlist);
1893 fail_1:
1894 PyMem_DEL(argvlist);
1895 Py_XDECREF(vals);
1896 Py_XDECREF(keys);
1897 return res;
1898}
1899#endif /* HAVE_SPAWNV */
1900
1901
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001902#ifdef HAVE_FORK1
1903static char posix_fork1__doc__[] =
1904"fork1() -> pid\n\
1905Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1906\n\
1907Return 0 to child process and PID of child to parent process.";
1908
1909static PyObject *
1910posix_fork1(self, args)
1911 PyObject *self;
1912 PyObject *args;
1913{
1914 int pid;
1915 if (!PyArg_ParseTuple(args, ":fork1"))
1916 return NULL;
1917 pid = fork1();
1918 if (pid == -1)
1919 return posix_error();
1920 PyOS_AfterFork();
1921 return PyInt_FromLong((long)pid);
1922}
1923#endif
1924
1925
Guido van Rossumad0ee831995-03-01 10:34:45 +00001926#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001927static char posix_fork__doc__[] =
1928"fork() -> pid\n\
1929Fork a child process.\n\
1930\n\
1931Return 0 to child process and PID of child to parent process.";
1932
Barry Warsaw53699e91996-12-10 23:23:01 +00001933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001934posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001935{
1936 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001937 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001938 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001939 pid = fork();
1940 if (pid == -1)
1941 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001942 if (pid == 0)
1943 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001944 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001945}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001946#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001947
Fred Drake8cef4cf2000-06-28 16:40:38 +00001948#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1949#ifdef HAVE_PTY_H
1950#include <pty.h>
1951#else
1952#ifdef HAVE_LIBUTIL_H
1953#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001954#endif /* HAVE_LIBUTIL_H */
1955#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001956#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001957
Thomas Wouters70c21a12000-07-14 14:28:33 +00001958#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001959static char posix_openpty__doc__[] =
1960"openpty() -> (master_fd, slave_fd)\n\
1961Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1962
1963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001964posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001965{
1966 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001967#ifndef HAVE_OPENPTY
1968 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001969#endif
1970
Fred Drake8cef4cf2000-06-28 16:40:38 +00001971 if (!PyArg_ParseTuple(args, ":openpty"))
1972 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001973
1974#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001975 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1976 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001977#else
1978 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1979 if (slave_name == NULL)
1980 return posix_error();
1981
1982 slave_fd = open(slave_name, O_RDWR);
1983 if (slave_fd < 0)
1984 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001985#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001986
Fred Drake8cef4cf2000-06-28 16:40:38 +00001987 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001988
Fred Drake8cef4cf2000-06-28 16:40:38 +00001989}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001990#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001991
1992#ifdef HAVE_FORKPTY
1993static char posix_forkpty__doc__[] =
1994"forkpty() -> (pid, master_fd)\n\
1995Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1996Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1997To both, return fd of newly opened pseudo-terminal.\n";
1998
1999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002000posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002001{
2002 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002003
Fred Drake8cef4cf2000-06-28 16:40:38 +00002004 if (!PyArg_ParseTuple(args, ":forkpty"))
2005 return NULL;
2006 pid = forkpty(&master_fd, NULL, NULL, NULL);
2007 if (pid == -1)
2008 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002009 if (pid == 0)
2010 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002011 return Py_BuildValue("(ii)", pid, master_fd);
2012}
2013#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Guido van Rossumad0ee831995-03-01 10:34:45 +00002015#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002016static char posix_getegid__doc__[] =
2017"getegid() -> egid\n\
2018Return the current process's effective group id.";
2019
Barry Warsaw53699e91996-12-10 23:23:01 +00002020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002021posix_getegid(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, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002024 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002025 return PyInt_FromLong((long)getegid());
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_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002031static char posix_geteuid__doc__[] =
2032"geteuid() -> euid\n\
2033Return the current process's effective user id.";
2034
Barry Warsaw53699e91996-12-10 23:23:01 +00002035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002036posix_geteuid(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, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002039 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002040 return PyInt_FromLong((long)geteuid());
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
Guido van Rossumad0ee831995-03-01 10:34:45 +00002045#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002046static char posix_getgid__doc__[] =
2047"getgid() -> gid\n\
2048Return the current process's group id.";
2049
Barry Warsaw53699e91996-12-10 23:23:01 +00002050static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002051posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002052{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002053 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002054 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002055 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002056}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002057#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059
2060static char posix_getpid__doc__[] =
2061"getpid() -> pid\n\
2062Return the current process id";
2063
Barry Warsaw53699e91996-12-10 23:23:01 +00002064static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002065posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002066{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002067 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002068 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002069 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002070}
2071
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002072
Fred Drakec9680921999-12-13 16:37:25 +00002073#ifdef HAVE_GETGROUPS
2074static char posix_getgroups__doc__[] = "\
2075getgroups() -> list of group IDs\n\
2076Return list of supplemental group IDs for the process.";
2077
2078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002079posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002080{
2081 PyObject *result = NULL;
2082
2083 if (PyArg_ParseTuple(args, ":getgroups")) {
2084#ifdef NGROUPS_MAX
2085#define MAX_GROUPS NGROUPS_MAX
2086#else
2087 /* defined to be 16 on Solaris7, so this should be a small number */
2088#define MAX_GROUPS 64
2089#endif
2090 gid_t grouplist[MAX_GROUPS];
2091 int n;
2092
2093 n = getgroups(MAX_GROUPS, grouplist);
2094 if (n < 0)
2095 posix_error();
2096 else {
2097 result = PyList_New(n);
2098 if (result != NULL) {
2099 PyObject *o;
2100 int i;
2101 for (i = 0; i < n; ++i) {
2102 o = PyInt_FromLong((long)grouplist[i]);
2103 if (o == NULL) {
2104 Py_DECREF(result);
2105 result = NULL;
2106 break;
2107 }
2108 PyList_SET_ITEM(result, i, o);
2109 }
2110 }
2111 }
2112 }
2113 return result;
2114}
2115#endif
2116
Guido van Rossumb6775db1994-08-01 11:34:53 +00002117#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002118static char posix_getpgrp__doc__[] =
2119"getpgrp() -> pgrp\n\
2120Return the current process group id.";
2121
Barry Warsaw53699e91996-12-10 23:23:01 +00002122static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002123posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002124{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002125 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002126 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002127#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002128 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002129#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002130 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002131#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002132}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002133#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002135
Guido van Rossumb6775db1994-08-01 11:34:53 +00002136#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002137static char posix_setpgrp__doc__[] =
2138"setpgrp() -> None\n\
2139Make this process a session leader.";
2140
Barry Warsaw53699e91996-12-10 23:23:01 +00002141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002142posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002143{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002144 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002145 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002146#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002147 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002148#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002149 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002150#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002151 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002152 Py_INCREF(Py_None);
2153 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002154}
2155
Guido van Rossumb6775db1994-08-01 11:34:53 +00002156#endif /* HAVE_SETPGRP */
2157
Guido van Rossumad0ee831995-03-01 10:34:45 +00002158#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002159static char posix_getppid__doc__[] =
2160"getppid() -> ppid\n\
2161Return the parent's process id.";
2162
Barry Warsaw53699e91996-12-10 23:23:01 +00002163static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002164posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002165{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002166 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002167 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002168 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002169}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002170#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002171
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002172
Fred Drake12c6e2d1999-12-14 21:25:03 +00002173#ifdef HAVE_GETLOGIN
2174static char posix_getlogin__doc__[] = "\
2175getlogin() -> string\n\
2176Return the actual login name.";
2177
2178static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002179posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002180{
2181 PyObject *result = NULL;
2182
2183 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002184 char *name;
2185 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002186
Fred Drakea30680b2000-12-06 21:24:28 +00002187 errno = 0;
2188 name = getlogin();
2189 if (name == NULL) {
2190 if (errno)
2191 posix_error();
2192 else
2193 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002194 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002195 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002196 else
2197 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002198 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002199 }
2200 return result;
2201}
2202#endif
2203
Guido van Rossumad0ee831995-03-01 10:34:45 +00002204#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002205static char posix_getuid__doc__[] =
2206"getuid() -> uid\n\
2207Return the current process's user id.";
2208
Barry Warsaw53699e91996-12-10 23:23:01 +00002209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002210posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002211{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002212 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002213 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002214 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002215}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002216#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002218
Guido van Rossumad0ee831995-03-01 10:34:45 +00002219#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002220static char posix_kill__doc__[] =
2221"kill(pid, sig) -> None\n\
2222Kill a process with a signal.";
2223
Barry Warsaw53699e91996-12-10 23:23:01 +00002224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002225posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002226{
2227 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002228 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002229 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002230#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002231 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2232 APIRET rc;
2233 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002234 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002235
2236 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2237 APIRET rc;
2238 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002239 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002240
2241 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002242 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002243#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002244 if (kill(pid, sig) == -1)
2245 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002246#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002247 Py_INCREF(Py_None);
2248 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002249}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002250#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002251
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002252#ifdef HAVE_KILLPG
2253static char posix_killpg__doc__[] =
2254"killpg(pgid, sig) -> None\n\
2255Kill a process group with a signal.";
2256
2257static PyObject *
2258posix_killpg(PyObject *self, PyObject *args)
2259{
2260 int pgid, sig;
2261 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2262 return NULL;
2263 if (killpg(pgid, sig) == -1)
2264 return posix_error();
2265 Py_INCREF(Py_None);
2266 return Py_None;
2267}
2268#endif
2269
Guido van Rossumc0125471996-06-28 18:55:32 +00002270#ifdef HAVE_PLOCK
2271
2272#ifdef HAVE_SYS_LOCK_H
2273#include <sys/lock.h>
2274#endif
2275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002276static char posix_plock__doc__[] =
2277"plock(op) -> None\n\
2278Lock program segments into memory.";
2279
Barry Warsaw53699e91996-12-10 23:23:01 +00002280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002281posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002282{
2283 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002284 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002285 return NULL;
2286 if (plock(op) == -1)
2287 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002288 Py_INCREF(Py_None);
2289 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002290}
2291#endif
2292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002293
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002294#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002295static char posix_popen__doc__[] =
2296"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2297Open a pipe to/from a command returning a file object.";
2298
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002299#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002300#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002301static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002302async_system(const char *command)
2303{
2304 char *p, errormsg[256], args[1024];
2305 RESULTCODES rcodes;
2306 APIRET rc;
2307 char *shell = getenv("COMSPEC");
2308 if (!shell)
2309 shell = "cmd";
2310
2311 strcpy(args, shell);
2312 p = &args[ strlen(args)+1 ];
2313 strcpy(p, "/c ");
2314 strcat(p, command);
2315 p += strlen(p) + 1;
2316 *p = '\0';
2317
2318 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002319 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002320 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002321 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002322 &rcodes, shell);
2323 return rc;
2324}
2325
Guido van Rossumd48f2521997-12-05 22:19:34 +00002326static FILE *
2327popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002328{
2329 HFILE rhan, whan;
2330 FILE *retfd = NULL;
2331 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2332
Guido van Rossumd48f2521997-12-05 22:19:34 +00002333 if (rc != NO_ERROR) {
2334 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002335 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002336 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002338 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2339 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002340
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002341 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2342 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002343
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002344 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2345 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002346
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002347 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002348 }
2349
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002350 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2351 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002352
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002353 if (rc == NO_ERROR)
2354 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2355
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002356 close(oldfd); /* And Close Saved STDOUT Handle */
2357 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002358
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002359 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2360 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002361
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002362 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2363 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002364
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002365 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2366 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002367
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002368 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002369 }
2370
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002371 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2372 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002373
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002374 if (rc == NO_ERROR)
2375 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2376
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002377 close(oldfd); /* And Close Saved STDIN Handle */
2378 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002379
Guido van Rossumd48f2521997-12-05 22:19:34 +00002380 } else {
2381 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002382 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002383 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002384}
2385
2386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002387posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002388{
2389 char *name;
2390 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002391 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002392 FILE *fp;
2393 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002394 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002395 return NULL;
2396 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002397 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002398 Py_END_ALLOW_THREADS
2399 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002400 return os2_error(err);
2401
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002402 f = PyFile_FromFile(fp, name, mode, fclose);
2403 if (f != NULL)
2404 PyFile_SetBufSize(f, bufsize);
2405 return f;
2406}
2407
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002408#elif defined(PYCC_GCC)
2409
2410/* standard posix version of popen() support */
2411static PyObject *
2412posix_popen(PyObject *self, PyObject *args)
2413{
2414 char *name;
2415 char *mode = "r";
2416 int bufsize = -1;
2417 FILE *fp;
2418 PyObject *f;
2419 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2420 return NULL;
2421 Py_BEGIN_ALLOW_THREADS
2422 fp = popen(name, mode);
2423 Py_END_ALLOW_THREADS
2424 if (fp == NULL)
2425 return posix_error();
2426 f = PyFile_FromFile(fp, name, mode, pclose);
2427 if (f != NULL)
2428 PyFile_SetBufSize(f, bufsize);
2429 return f;
2430}
2431
2432/* fork() under OS/2 has lots'o'warts
2433 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2434 * most of this code is a ripoff of the win32 code, but using the
2435 * capabilities of EMX's C library routines
2436 */
2437
2438/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2439#define POPEN_1 1
2440#define POPEN_2 2
2441#define POPEN_3 3
2442#define POPEN_4 4
2443
2444static PyObject *_PyPopen(char *, int, int, int);
2445static int _PyPclose(FILE *file);
2446
2447/*
2448 * Internal dictionary mapping popen* file pointers to process handles,
2449 * for use when retrieving the process exit code. See _PyPclose() below
2450 * for more information on this dictionary's use.
2451 */
2452static PyObject *_PyPopenProcs = NULL;
2453
2454/* os2emx version of popen2()
2455 *
2456 * The result of this function is a pipe (file) connected to the
2457 * process's stdin, and a pipe connected to the process's stdout.
2458 */
2459
2460static PyObject *
2461os2emx_popen2(PyObject *self, PyObject *args)
2462{
2463 PyObject *f;
2464 int tm=0;
2465
2466 char *cmdstring;
2467 char *mode = "t";
2468 int bufsize = -1;
2469 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2470 return NULL;
2471
2472 if (*mode == 't')
2473 tm = O_TEXT;
2474 else if (*mode != 'b') {
2475 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2476 return NULL;
2477 } else
2478 tm = O_BINARY;
2479
2480 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2481
2482 return f;
2483}
2484
2485/*
2486 * Variation on os2emx.popen2
2487 *
2488 * The result of this function is 3 pipes - the process's stdin,
2489 * stdout and stderr
2490 */
2491
2492static PyObject *
2493os2emx_popen3(PyObject *self, PyObject *args)
2494{
2495 PyObject *f;
2496 int tm = 0;
2497
2498 char *cmdstring;
2499 char *mode = "t";
2500 int bufsize = -1;
2501 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2502 return NULL;
2503
2504 if (*mode == 't')
2505 tm = O_TEXT;
2506 else if (*mode != 'b') {
2507 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2508 return NULL;
2509 } else
2510 tm = O_BINARY;
2511
2512 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2513
2514 return f;
2515}
2516
2517/*
2518 * Variation on os2emx.popen2
2519 *
2520 * The result of this function is 2 pipes - the processes stdin,
2521 * and stdout+stderr combined as a single pipe.
2522 */
2523
2524static PyObject *
2525os2emx_popen4(PyObject *self, PyObject *args)
2526{
2527 PyObject *f;
2528 int tm = 0;
2529
2530 char *cmdstring;
2531 char *mode = "t";
2532 int bufsize = -1;
2533 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2534 return NULL;
2535
2536 if (*mode == 't')
2537 tm = O_TEXT;
2538 else if (*mode != 'b') {
2539 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2540 return NULL;
2541 } else
2542 tm = O_BINARY;
2543
2544 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2545
2546 return f;
2547}
2548
2549/* a couple of structures for convenient handling of multiple
2550 * file handles and pipes
2551 */
2552struct file_ref
2553{
2554 int handle;
2555 int flags;
2556};
2557
2558struct pipe_ref
2559{
2560 int rd;
2561 int wr;
2562};
2563
2564/* The following code is derived from the win32 code */
2565
2566static PyObject *
2567_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2568{
2569 struct file_ref stdio[3];
2570 struct pipe_ref p_fd[3];
2571 FILE *p_s[3];
2572 int file_count, i, pipe_err, pipe_pid;
2573 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2574 PyObject *f, *p_f[3];
2575
2576 /* file modes for subsequent fdopen's on pipe handles */
2577 if (mode == O_TEXT)
2578 {
2579 rd_mode = "rt";
2580 wr_mode = "wt";
2581 }
2582 else
2583 {
2584 rd_mode = "rb";
2585 wr_mode = "wb";
2586 }
2587
2588 /* prepare shell references */
2589 if ((shell = getenv("EMXSHELL")) == NULL)
2590 if ((shell = getenv("COMSPEC")) == NULL)
2591 {
2592 errno = ENOENT;
2593 return posix_error();
2594 }
2595
2596 sh_name = _getname(shell);
2597 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2598 opt = "/c";
2599 else
2600 opt = "-c";
2601
2602 /* save current stdio fds + their flags, and set not inheritable */
2603 i = pipe_err = 0;
2604 while (pipe_err >= 0 && i < 3)
2605 {
2606 pipe_err = stdio[i].handle = dup(i);
2607 stdio[i].flags = fcntl(i, F_GETFD, 0);
2608 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2609 i++;
2610 }
2611 if (pipe_err < 0)
2612 {
2613 /* didn't get them all saved - clean up and bail out */
2614 int saved_err = errno;
2615 while (i-- > 0)
2616 {
2617 close(stdio[i].handle);
2618 }
2619 errno = saved_err;
2620 return posix_error();
2621 }
2622
2623 /* create pipe ends */
2624 file_count = 2;
2625 if (n == POPEN_3)
2626 file_count = 3;
2627 i = pipe_err = 0;
2628 while ((pipe_err == 0) && (i < file_count))
2629 pipe_err = pipe((int *)&p_fd[i++]);
2630 if (pipe_err < 0)
2631 {
2632 /* didn't get them all made - clean up and bail out */
2633 while (i-- > 0)
2634 {
2635 close(p_fd[i].wr);
2636 close(p_fd[i].rd);
2637 }
2638 errno = EPIPE;
2639 return posix_error();
2640 }
2641
2642 /* change the actual standard IO streams over temporarily,
2643 * making the retained pipe ends non-inheritable
2644 */
2645 pipe_err = 0;
2646
2647 /* - stdin */
2648 if (dup2(p_fd[0].rd, 0) == 0)
2649 {
2650 close(p_fd[0].rd);
2651 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2652 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2653 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2654 {
2655 close(p_fd[0].wr);
2656 pipe_err = -1;
2657 }
2658 }
2659 else
2660 {
2661 pipe_err = -1;
2662 }
2663
2664 /* - stdout */
2665 if (pipe_err == 0)
2666 {
2667 if (dup2(p_fd[1].wr, 1) == 1)
2668 {
2669 close(p_fd[1].wr);
2670 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2671 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2672 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2673 {
2674 close(p_fd[1].rd);
2675 pipe_err = -1;
2676 }
2677 }
2678 else
2679 {
2680 pipe_err = -1;
2681 }
2682 }
2683
2684 /* - stderr, as required */
2685 if (pipe_err == 0)
2686 switch (n)
2687 {
2688 case POPEN_3:
2689 {
2690 if (dup2(p_fd[2].wr, 2) == 2)
2691 {
2692 close(p_fd[2].wr);
2693 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2694 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2695 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2696 {
2697 close(p_fd[2].rd);
2698 pipe_err = -1;
2699 }
2700 }
2701 else
2702 {
2703 pipe_err = -1;
2704 }
2705 break;
2706 }
2707
2708 case POPEN_4:
2709 {
2710 if (dup2(1, 2) != 2)
2711 {
2712 pipe_err = -1;
2713 }
2714 break;
2715 }
2716 }
2717
2718 /* spawn the child process */
2719 if (pipe_err == 0)
2720 {
2721 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2722 if (pipe_pid == -1)
2723 {
2724 pipe_err = -1;
2725 }
2726 else
2727 {
2728 /* save the PID into the FILE structure
2729 * NOTE: this implementation doesn't actually
2730 * take advantage of this, but do it for
2731 * completeness - AIM Apr01
2732 */
2733 for (i = 0; i < file_count; i++)
2734 p_s[i]->_pid = pipe_pid;
2735 }
2736 }
2737
2738 /* reset standard IO to normal */
2739 for (i = 0; i < 3; i++)
2740 {
2741 dup2(stdio[i].handle, i);
2742 fcntl(i, F_SETFD, stdio[i].flags);
2743 close(stdio[i].handle);
2744 }
2745
2746 /* if any remnant problems, clean up and bail out */
2747 if (pipe_err < 0)
2748 {
2749 for (i = 0; i < 3; i++)
2750 {
2751 close(p_fd[i].rd);
2752 close(p_fd[i].wr);
2753 }
2754 errno = EPIPE;
2755 return posix_error_with_filename(cmdstring);
2756 }
2757
2758 /* build tuple of file objects to return */
2759 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2760 PyFile_SetBufSize(p_f[0], bufsize);
2761 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2762 PyFile_SetBufSize(p_f[1], bufsize);
2763 if (n == POPEN_3)
2764 {
2765 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2766 PyFile_SetBufSize(p_f[0], bufsize);
2767 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2768 }
2769 else
2770 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2771
2772 /*
2773 * Insert the files we've created into the process dictionary
2774 * all referencing the list with the process handle and the
2775 * initial number of files (see description below in _PyPclose).
2776 * Since if _PyPclose later tried to wait on a process when all
2777 * handles weren't closed, it could create a deadlock with the
2778 * child, we spend some energy here to try to ensure that we
2779 * either insert all file handles into the dictionary or none
2780 * at all. It's a little clumsy with the various popen modes
2781 * and variable number of files involved.
2782 */
2783 if (!_PyPopenProcs)
2784 {
2785 _PyPopenProcs = PyDict_New();
2786 }
2787
2788 if (_PyPopenProcs)
2789 {
2790 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2791 int ins_rc[3];
2792
2793 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2794 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2795
2796 procObj = PyList_New(2);
2797 pidObj = PyInt_FromLong((long) pipe_pid);
2798 intObj = PyInt_FromLong((long) file_count);
2799
2800 if (procObj && pidObj && intObj)
2801 {
2802 PyList_SetItem(procObj, 0, pidObj);
2803 PyList_SetItem(procObj, 1, intObj);
2804
2805 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2806 if (fileObj[0])
2807 {
2808 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2809 fileObj[0],
2810 procObj);
2811 }
2812 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2813 if (fileObj[1])
2814 {
2815 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2816 fileObj[1],
2817 procObj);
2818 }
2819 if (file_count >= 3)
2820 {
2821 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2822 if (fileObj[2])
2823 {
2824 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2825 fileObj[2],
2826 procObj);
2827 }
2828 }
2829
2830 if (ins_rc[0] < 0 || !fileObj[0] ||
2831 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2832 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2833 {
2834 /* Something failed - remove any dictionary
2835 * entries that did make it.
2836 */
2837 if (!ins_rc[0] && fileObj[0])
2838 {
2839 PyDict_DelItem(_PyPopenProcs,
2840 fileObj[0]);
2841 }
2842 if (!ins_rc[1] && fileObj[1])
2843 {
2844 PyDict_DelItem(_PyPopenProcs,
2845 fileObj[1]);
2846 }
2847 if (!ins_rc[2] && fileObj[2])
2848 {
2849 PyDict_DelItem(_PyPopenProcs,
2850 fileObj[2]);
2851 }
2852 }
2853 }
2854
2855 /*
2856 * Clean up our localized references for the dictionary keys
2857 * and value since PyDict_SetItem will Py_INCREF any copies
2858 * that got placed in the dictionary.
2859 */
2860 Py_XDECREF(procObj);
2861 Py_XDECREF(fileObj[0]);
2862 Py_XDECREF(fileObj[1]);
2863 Py_XDECREF(fileObj[2]);
2864 }
2865
2866 /* Child is launched. */
2867 return f;
2868}
2869
2870/*
2871 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2872 * exit code for the child process and return as a result of the close.
2873 *
2874 * This function uses the _PyPopenProcs dictionary in order to map the
2875 * input file pointer to information about the process that was
2876 * originally created by the popen* call that created the file pointer.
2877 * The dictionary uses the file pointer as a key (with one entry
2878 * inserted for each file returned by the original popen* call) and a
2879 * single list object as the value for all files from a single call.
2880 * The list object contains the Win32 process handle at [0], and a file
2881 * count at [1], which is initialized to the total number of file
2882 * handles using that list.
2883 *
2884 * This function closes whichever handle it is passed, and decrements
2885 * the file count in the dictionary for the process handle pointed to
2886 * by this file. On the last close (when the file count reaches zero),
2887 * this function will wait for the child process and then return its
2888 * exit code as the result of the close() operation. This permits the
2889 * files to be closed in any order - it is always the close() of the
2890 * final handle that will return the exit code.
2891 */
2892
2893 /* RED_FLAG 31-Aug-2000 Tim
2894 * This is always called (today!) between a pair of
2895 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2896 * macros. So the thread running this has no valid thread state, as
2897 * far as Python is concerned. However, this calls some Python API
2898 * functions that cannot be called safely without a valid thread
2899 * state, in particular PyDict_GetItem.
2900 * As a temporary hack (although it may last for years ...), we
2901 * *rely* on not having a valid thread state in this function, in
2902 * order to create our own "from scratch".
2903 * This will deadlock if _PyPclose is ever called by a thread
2904 * holding the global lock.
2905 * (The OS/2 EMX thread support appears to cover the case where the
2906 * lock is already held - AIM Apr01)
2907 */
2908
2909static int _PyPclose(FILE *file)
2910{
2911 int result;
2912 int exit_code;
2913 int pipe_pid;
2914 PyObject *procObj, *pidObj, *intObj, *fileObj;
2915 int file_count;
2916#ifdef WITH_THREAD
2917 PyInterpreterState* pInterpreterState;
2918 PyThreadState* pThreadState;
2919#endif
2920
2921 /* Close the file handle first, to ensure it can't block the
2922 * child from exiting if it's the last handle.
2923 */
2924 result = fclose(file);
2925
2926#ifdef WITH_THREAD
2927 /* Bootstrap a valid thread state into existence. */
2928 pInterpreterState = PyInterpreterState_New();
2929 if (!pInterpreterState) {
2930 /* Well, we're hosed now! We don't have a thread
2931 * state, so can't call a nice error routine, or raise
2932 * an exception. Just die.
2933 */
2934 Py_FatalError("unable to allocate interpreter state "
2935 "when closing popen object.");
2936 return -1; /* unreachable */
2937 }
2938 pThreadState = PyThreadState_New(pInterpreterState);
2939 if (!pThreadState) {
2940 Py_FatalError("unable to allocate thread state "
2941 "when closing popen object.");
2942 return -1; /* unreachable */
2943 }
2944 /* Grab the global lock. Note that this will deadlock if the
2945 * current thread already has the lock! (see RED_FLAG comments
2946 * before this function)
2947 */
2948 PyEval_RestoreThread(pThreadState);
2949#endif
2950
2951 if (_PyPopenProcs)
2952 {
2953 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2954 (procObj = PyDict_GetItem(_PyPopenProcs,
2955 fileObj)) != NULL &&
2956 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2957 (intObj = PyList_GetItem(procObj,1)) != NULL)
2958 {
2959 pipe_pid = (int) PyInt_AsLong(pidObj);
2960 file_count = (int) PyInt_AsLong(intObj);
2961
2962 if (file_count > 1)
2963 {
2964 /* Still other files referencing process */
2965 file_count--;
2966 PyList_SetItem(procObj,1,
2967 PyInt_FromLong((long) file_count));
2968 }
2969 else
2970 {
2971 /* Last file for this process */
2972 if (result != EOF &&
2973 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2974 {
2975 /* extract exit status */
2976 if (WIFEXITED(exit_code))
2977 {
2978 result = WEXITSTATUS(exit_code);
2979 }
2980 else
2981 {
2982 errno = EPIPE;
2983 result = -1;
2984 }
2985 }
2986 else
2987 {
2988 /* Indicate failure - this will cause the file object
2989 * to raise an I/O error and translate the last
2990 * error code from errno. We do have a problem with
2991 * last errors that overlap the normal errno table,
2992 * but that's a consistent problem with the file object.
2993 */
2994 result = -1;
2995 }
2996 }
2997
2998 /* Remove this file pointer from dictionary */
2999 PyDict_DelItem(_PyPopenProcs, fileObj);
3000
3001 if (PyDict_Size(_PyPopenProcs) == 0)
3002 {
3003 Py_DECREF(_PyPopenProcs);
3004 _PyPopenProcs = NULL;
3005 }
3006
3007 } /* if object retrieval ok */
3008
3009 Py_XDECREF(fileObj);
3010 } /* if _PyPopenProcs */
3011
3012#ifdef WITH_THREAD
3013 /* Tear down the thread & interpreter states.
3014 * Note that interpreter state clear & delete functions automatically
3015 * call the thread clear & delete functions, and indeed insist on
3016 * doing that themselves. The lock must be held during the clear, but
3017 * need not be held during the delete.
3018 */
3019 PyInterpreterState_Clear(pInterpreterState);
3020 PyEval_ReleaseThread(pThreadState);
3021 PyInterpreterState_Delete(pInterpreterState);
3022#endif
3023
3024 return result;
3025}
3026
3027#endif /* PYCC_??? */
3028
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003029#elif defined(MS_WIN32)
3030
3031/*
3032 * Portable 'popen' replacement for Win32.
3033 *
3034 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3035 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003036 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003037 */
3038
3039#include <malloc.h>
3040#include <io.h>
3041#include <fcntl.h>
3042
3043/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3044#define POPEN_1 1
3045#define POPEN_2 2
3046#define POPEN_3 3
3047#define POPEN_4 4
3048
3049static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003050static int _PyPclose(FILE *file);
3051
3052/*
3053 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003054 * for use when retrieving the process exit code. See _PyPclose() below
3055 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003056 */
3057static PyObject *_PyPopenProcs = NULL;
3058
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003059
3060/* popen that works from a GUI.
3061 *
3062 * The result of this function is a pipe (file) connected to the
3063 * processes stdin or stdout, depending on the requested mode.
3064 */
3065
3066static PyObject *
3067posix_popen(PyObject *self, PyObject *args)
3068{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003069 PyObject *f, *s;
3070 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003071
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003072 char *cmdstring;
3073 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003074 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003075 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003076 return NULL;
3077
3078 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003079
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003080 if (*mode == 'r')
3081 tm = _O_RDONLY;
3082 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003083 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003084 return NULL;
3085 } else
3086 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003087
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003088 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003089 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003090 return NULL;
3091 }
3092
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003093 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003094 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003095 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003096 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003097 else
3098 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3099
3100 return f;
3101}
3102
3103/* Variation on win32pipe.popen
3104 *
3105 * The result of this function is a pipe (file) connected to the
3106 * process's stdin, and a pipe connected to the process's stdout.
3107 */
3108
3109static PyObject *
3110win32_popen2(PyObject *self, PyObject *args)
3111{
3112 PyObject *f;
3113 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003114
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003115 char *cmdstring;
3116 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003117 int bufsize = -1;
3118 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003119 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003120
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003121 if (*mode == 't')
3122 tm = _O_TEXT;
3123 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003124 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003125 return NULL;
3126 } else
3127 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003128
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003129 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003130 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003131 return NULL;
3132 }
3133
3134 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003135
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003136 return f;
3137}
3138
3139/*
3140 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003141 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003142 * The result of this function is 3 pipes - the process's stdin,
3143 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003144 */
3145
3146static PyObject *
3147win32_popen3(PyObject *self, PyObject *args)
3148{
3149 PyObject *f;
3150 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003151
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003152 char *cmdstring;
3153 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003154 int bufsize = -1;
3155 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003156 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003157
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003158 if (*mode == 't')
3159 tm = _O_TEXT;
3160 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003161 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003162 return NULL;
3163 } else
3164 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003165
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003166 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003167 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003168 return NULL;
3169 }
3170
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003171 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003172
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003173 return f;
3174}
3175
3176/*
3177 * Variation on win32pipe.popen
3178 *
Tim Peters5aa91602002-01-30 05:46:57 +00003179 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003180 * and stdout+stderr combined as a single pipe.
3181 */
3182
3183static PyObject *
3184win32_popen4(PyObject *self, PyObject *args)
3185{
3186 PyObject *f;
3187 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003188
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003189 char *cmdstring;
3190 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003191 int bufsize = -1;
3192 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003193 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003194
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003195 if (*mode == 't')
3196 tm = _O_TEXT;
3197 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003198 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003199 return NULL;
3200 } else
3201 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003202
3203 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003204 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003205 return NULL;
3206 }
3207
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003208 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003209
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003210 return f;
3211}
3212
Mark Hammond08501372001-01-31 07:30:29 +00003213static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003214_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003215 HANDLE hStdin,
3216 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003217 HANDLE hStderr,
3218 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003219{
3220 PROCESS_INFORMATION piProcInfo;
3221 STARTUPINFO siStartInfo;
3222 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003223 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003224 int i;
3225 int x;
3226
3227 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003228 char *comshell;
3229
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003230 s1 = (char *)_alloca(i);
3231 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3232 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003233
3234 /* Explicitly check if we are using COMMAND.COM. If we are
3235 * then use the w9xpopen hack.
3236 */
3237 comshell = s1 + x;
3238 while (comshell >= s1 && *comshell != '\\')
3239 --comshell;
3240 ++comshell;
3241
3242 if (GetVersion() < 0x80000000 &&
3243 _stricmp(comshell, "command.com") != 0) {
3244 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003245 x = i + strlen(s3) + strlen(cmdstring) + 1;
3246 s2 = (char *)_alloca(x);
3247 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003248 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003249 }
3250 else {
3251 /*
Tim Peters402d5982001-08-27 06:37:48 +00003252 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3253 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003254 */
Mark Hammond08501372001-01-31 07:30:29 +00003255 char modulepath[_MAX_PATH];
3256 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003257 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3258 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003259 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003260 x = i+1;
3261 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003262 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003263 strncat(modulepath,
3264 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003265 (sizeof(modulepath)/sizeof(modulepath[0]))
3266 -strlen(modulepath));
3267 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003268 /* Eeek - file-not-found - possibly an embedding
3269 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003270 */
Tim Peters5aa91602002-01-30 05:46:57 +00003271 strncpy(modulepath,
3272 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003273 sizeof(modulepath)/sizeof(modulepath[0]));
3274 if (modulepath[strlen(modulepath)-1] != '\\')
3275 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003276 strncat(modulepath,
3277 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003278 (sizeof(modulepath)/sizeof(modulepath[0]))
3279 -strlen(modulepath));
3280 /* No where else to look - raise an easily identifiable
3281 error, rather than leaving Windows to report
3282 "file not found" - as the user is probably blissfully
3283 unaware this shim EXE is used, and it will confuse them.
3284 (well, it confused me for a while ;-)
3285 */
3286 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003287 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003288 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003289 "for popen to work with your shell "
3290 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003291 szConsoleSpawn);
3292 return FALSE;
3293 }
3294 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003295 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003296 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003297 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003298
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003299 s2 = (char *)_alloca(x);
3300 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003301 /* To maintain correct argument passing semantics,
3302 we pass the command-line as it stands, and allow
3303 quoting to be applied. w9xpopen.exe will then
3304 use its argv vector, and re-quote the necessary
3305 args for the ultimate child process.
3306 */
Tim Peters75cdad52001-11-28 22:07:30 +00003307 PyOS_snprintf(
3308 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003309 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003310 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003311 s1,
3312 s3,
3313 cmdstring);
3314 }
3315 }
3316
3317 /* Could be an else here to try cmd.exe / command.com in the path
3318 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003319 else {
Tim Peters402d5982001-08-27 06:37:48 +00003320 PyErr_SetString(PyExc_RuntimeError,
3321 "Cannot locate a COMSPEC environment variable to "
3322 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003323 return FALSE;
3324 }
Tim Peters5aa91602002-01-30 05:46:57 +00003325
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003326 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3327 siStartInfo.cb = sizeof(STARTUPINFO);
3328 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3329 siStartInfo.hStdInput = hStdin;
3330 siStartInfo.hStdOutput = hStdout;
3331 siStartInfo.hStdError = hStderr;
3332 siStartInfo.wShowWindow = SW_HIDE;
3333
3334 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003335 s2,
3336 NULL,
3337 NULL,
3338 TRUE,
3339 CREATE_NEW_CONSOLE,
3340 NULL,
3341 NULL,
3342 &siStartInfo,
3343 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003344 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003345 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003346
Mark Hammondb37a3732000-08-14 04:47:33 +00003347 /* Return process handle */
3348 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003349 return TRUE;
3350 }
Tim Peters402d5982001-08-27 06:37:48 +00003351 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003352 return FALSE;
3353}
3354
3355/* The following code is based off of KB: Q190351 */
3356
3357static PyObject *
3358_PyPopen(char *cmdstring, int mode, int n)
3359{
3360 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3361 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003362 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003363
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003364 SECURITY_ATTRIBUTES saAttr;
3365 BOOL fSuccess;
3366 int fd1, fd2, fd3;
3367 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003368 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003369 PyObject *f;
3370
3371 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3372 saAttr.bInheritHandle = TRUE;
3373 saAttr.lpSecurityDescriptor = NULL;
3374
3375 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3376 return win32_error("CreatePipe", NULL);
3377
3378 /* Create new output read handle and the input write handle. Set
3379 * the inheritance properties to FALSE. Otherwise, the child inherits
3380 * the these handles; resulting in non-closeable handles to the pipes
3381 * being created. */
3382 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003383 GetCurrentProcess(), &hChildStdinWrDup, 0,
3384 FALSE,
3385 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003386 if (!fSuccess)
3387 return win32_error("DuplicateHandle", NULL);
3388
3389 /* Close the inheritable version of ChildStdin
3390 that we're using. */
3391 CloseHandle(hChildStdinWr);
3392
3393 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3394 return win32_error("CreatePipe", NULL);
3395
3396 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003397 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3398 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003399 if (!fSuccess)
3400 return win32_error("DuplicateHandle", NULL);
3401
3402 /* Close the inheritable version of ChildStdout
3403 that we're using. */
3404 CloseHandle(hChildStdoutRd);
3405
3406 if (n != POPEN_4) {
3407 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3408 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003409 fSuccess = DuplicateHandle(GetCurrentProcess(),
3410 hChildStderrRd,
3411 GetCurrentProcess(),
3412 &hChildStderrRdDup, 0,
3413 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003414 if (!fSuccess)
3415 return win32_error("DuplicateHandle", NULL);
3416 /* Close the inheritable version of ChildStdErr that we're using. */
3417 CloseHandle(hChildStderrRd);
3418 }
Tim Peters5aa91602002-01-30 05:46:57 +00003419
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003420 switch (n) {
3421 case POPEN_1:
3422 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3423 case _O_WRONLY | _O_TEXT:
3424 /* Case for writing to child Stdin in text mode. */
3425 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3426 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003427 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003428 PyFile_SetBufSize(f, 0);
3429 /* We don't care about these pipes anymore, so close them. */
3430 CloseHandle(hChildStdoutRdDup);
3431 CloseHandle(hChildStderrRdDup);
3432 break;
3433
3434 case _O_RDONLY | _O_TEXT:
3435 /* Case for reading from child Stdout in text mode. */
3436 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3437 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003438 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003439 PyFile_SetBufSize(f, 0);
3440 /* We don't care about these pipes anymore, so close them. */
3441 CloseHandle(hChildStdinWrDup);
3442 CloseHandle(hChildStderrRdDup);
3443 break;
3444
3445 case _O_RDONLY | _O_BINARY:
3446 /* Case for readinig from child Stdout in binary mode. */
3447 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3448 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003449 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003450 PyFile_SetBufSize(f, 0);
3451 /* We don't care about these pipes anymore, so close them. */
3452 CloseHandle(hChildStdinWrDup);
3453 CloseHandle(hChildStderrRdDup);
3454 break;
3455
3456 case _O_WRONLY | _O_BINARY:
3457 /* Case for writing to child Stdin in binary mode. */
3458 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3459 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003460 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003461 PyFile_SetBufSize(f, 0);
3462 /* We don't care about these pipes anymore, so close them. */
3463 CloseHandle(hChildStdoutRdDup);
3464 CloseHandle(hChildStderrRdDup);
3465 break;
3466 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003467 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003468 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003469
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003470 case POPEN_2:
3471 case POPEN_4:
3472 {
3473 char *m1, *m2;
3474 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003475
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003476 if (mode && _O_TEXT) {
3477 m1 = "r";
3478 m2 = "w";
3479 } else {
3480 m1 = "rb";
3481 m2 = "wb";
3482 }
3483
3484 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3485 f1 = _fdopen(fd1, m2);
3486 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3487 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003488 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003489 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003490 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003491 PyFile_SetBufSize(p2, 0);
3492
3493 if (n != 4)
3494 CloseHandle(hChildStderrRdDup);
3495
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003496 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003497 Py_XDECREF(p1);
3498 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003499 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003500 break;
3501 }
Tim Peters5aa91602002-01-30 05:46:57 +00003502
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003503 case POPEN_3:
3504 {
3505 char *m1, *m2;
3506 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003507
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003508 if (mode && _O_TEXT) {
3509 m1 = "r";
3510 m2 = "w";
3511 } else {
3512 m1 = "rb";
3513 m2 = "wb";
3514 }
3515
3516 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3517 f1 = _fdopen(fd1, m2);
3518 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3519 f2 = _fdopen(fd2, m1);
3520 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3521 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003522 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003523 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3524 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003525 PyFile_SetBufSize(p1, 0);
3526 PyFile_SetBufSize(p2, 0);
3527 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003528 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003529 Py_XDECREF(p1);
3530 Py_XDECREF(p2);
3531 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003532 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003533 break;
3534 }
3535 }
3536
3537 if (n == POPEN_4) {
3538 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003539 hChildStdinRd,
3540 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003541 hChildStdoutWr,
3542 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003543 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003544 }
3545 else {
3546 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003547 hChildStdinRd,
3548 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003549 hChildStderrWr,
3550 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003551 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003552 }
3553
Mark Hammondb37a3732000-08-14 04:47:33 +00003554 /*
3555 * Insert the files we've created into the process dictionary
3556 * all referencing the list with the process handle and the
3557 * initial number of files (see description below in _PyPclose).
3558 * Since if _PyPclose later tried to wait on a process when all
3559 * handles weren't closed, it could create a deadlock with the
3560 * child, we spend some energy here to try to ensure that we
3561 * either insert all file handles into the dictionary or none
3562 * at all. It's a little clumsy with the various popen modes
3563 * and variable number of files involved.
3564 */
3565 if (!_PyPopenProcs) {
3566 _PyPopenProcs = PyDict_New();
3567 }
3568
3569 if (_PyPopenProcs) {
3570 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3571 int ins_rc[3];
3572
3573 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3574 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3575
3576 procObj = PyList_New(2);
3577 hProcessObj = PyLong_FromVoidPtr(hProcess);
3578 intObj = PyInt_FromLong(file_count);
3579
3580 if (procObj && hProcessObj && intObj) {
3581 PyList_SetItem(procObj,0,hProcessObj);
3582 PyList_SetItem(procObj,1,intObj);
3583
3584 fileObj[0] = PyLong_FromVoidPtr(f1);
3585 if (fileObj[0]) {
3586 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3587 fileObj[0],
3588 procObj);
3589 }
3590 if (file_count >= 2) {
3591 fileObj[1] = PyLong_FromVoidPtr(f2);
3592 if (fileObj[1]) {
3593 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3594 fileObj[1],
3595 procObj);
3596 }
3597 }
3598 if (file_count >= 3) {
3599 fileObj[2] = PyLong_FromVoidPtr(f3);
3600 if (fileObj[2]) {
3601 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3602 fileObj[2],
3603 procObj);
3604 }
3605 }
3606
3607 if (ins_rc[0] < 0 || !fileObj[0] ||
3608 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3609 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3610 /* Something failed - remove any dictionary
3611 * entries that did make it.
3612 */
3613 if (!ins_rc[0] && fileObj[0]) {
3614 PyDict_DelItem(_PyPopenProcs,
3615 fileObj[0]);
3616 }
3617 if (!ins_rc[1] && fileObj[1]) {
3618 PyDict_DelItem(_PyPopenProcs,
3619 fileObj[1]);
3620 }
3621 if (!ins_rc[2] && fileObj[2]) {
3622 PyDict_DelItem(_PyPopenProcs,
3623 fileObj[2]);
3624 }
3625 }
3626 }
Tim Peters5aa91602002-01-30 05:46:57 +00003627
Mark Hammondb37a3732000-08-14 04:47:33 +00003628 /*
3629 * Clean up our localized references for the dictionary keys
3630 * and value since PyDict_SetItem will Py_INCREF any copies
3631 * that got placed in the dictionary.
3632 */
3633 Py_XDECREF(procObj);
3634 Py_XDECREF(fileObj[0]);
3635 Py_XDECREF(fileObj[1]);
3636 Py_XDECREF(fileObj[2]);
3637 }
3638
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003639 /* Child is launched. Close the parents copy of those pipe
3640 * handles that only the child should have open. You need to
3641 * make sure that no handles to the write end of the output pipe
3642 * are maintained in this process or else the pipe will not close
3643 * when the child process exits and the ReadFile will hang. */
3644
3645 if (!CloseHandle(hChildStdinRd))
3646 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003647
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003648 if (!CloseHandle(hChildStdoutWr))
3649 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003650
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003651 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3652 return win32_error("CloseHandle", NULL);
3653
3654 return f;
3655}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003656
3657/*
3658 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3659 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003660 *
3661 * This function uses the _PyPopenProcs dictionary in order to map the
3662 * input file pointer to information about the process that was
3663 * originally created by the popen* call that created the file pointer.
3664 * The dictionary uses the file pointer as a key (with one entry
3665 * inserted for each file returned by the original popen* call) and a
3666 * single list object as the value for all files from a single call.
3667 * The list object contains the Win32 process handle at [0], and a file
3668 * count at [1], which is initialized to the total number of file
3669 * handles using that list.
3670 *
3671 * This function closes whichever handle it is passed, and decrements
3672 * the file count in the dictionary for the process handle pointed to
3673 * by this file. On the last close (when the file count reaches zero),
3674 * this function will wait for the child process and then return its
3675 * exit code as the result of the close() operation. This permits the
3676 * files to be closed in any order - it is always the close() of the
3677 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003678 */
Tim Peters736aa322000-09-01 06:51:24 +00003679
3680 /* RED_FLAG 31-Aug-2000 Tim
3681 * This is always called (today!) between a pair of
3682 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3683 * macros. So the thread running this has no valid thread state, as
3684 * far as Python is concerned. However, this calls some Python API
3685 * functions that cannot be called safely without a valid thread
3686 * state, in particular PyDict_GetItem.
3687 * As a temporary hack (although it may last for years ...), we
3688 * *rely* on not having a valid thread state in this function, in
3689 * order to create our own "from scratch".
3690 * This will deadlock if _PyPclose is ever called by a thread
3691 * holding the global lock.
3692 */
3693
Fredrik Lundh56055a42000-07-23 19:47:12 +00003694static int _PyPclose(FILE *file)
3695{
Fredrik Lundh20318932000-07-26 17:29:12 +00003696 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003697 DWORD exit_code;
3698 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003699 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3700 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003701#ifdef WITH_THREAD
3702 PyInterpreterState* pInterpreterState;
3703 PyThreadState* pThreadState;
3704#endif
3705
Fredrik Lundh20318932000-07-26 17:29:12 +00003706 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003707 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003708 */
3709 result = fclose(file);
3710
Tim Peters736aa322000-09-01 06:51:24 +00003711#ifdef WITH_THREAD
3712 /* Bootstrap a valid thread state into existence. */
3713 pInterpreterState = PyInterpreterState_New();
3714 if (!pInterpreterState) {
3715 /* Well, we're hosed now! We don't have a thread
3716 * state, so can't call a nice error routine, or raise
3717 * an exception. Just die.
3718 */
3719 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003720 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003721 return -1; /* unreachable */
3722 }
3723 pThreadState = PyThreadState_New(pInterpreterState);
3724 if (!pThreadState) {
3725 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003726 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003727 return -1; /* unreachable */
3728 }
3729 /* Grab the global lock. Note that this will deadlock if the
3730 * current thread already has the lock! (see RED_FLAG comments
3731 * before this function)
3732 */
3733 PyEval_RestoreThread(pThreadState);
3734#endif
3735
Fredrik Lundh56055a42000-07-23 19:47:12 +00003736 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003737 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3738 (procObj = PyDict_GetItem(_PyPopenProcs,
3739 fileObj)) != NULL &&
3740 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3741 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3742
3743 hProcess = PyLong_AsVoidPtr(hProcessObj);
3744 file_count = PyInt_AsLong(intObj);
3745
3746 if (file_count > 1) {
3747 /* Still other files referencing process */
3748 file_count--;
3749 PyList_SetItem(procObj,1,
3750 PyInt_FromLong(file_count));
3751 } else {
3752 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003753 if (result != EOF &&
3754 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3755 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003756 /* Possible truncation here in 16-bit environments, but
3757 * real exit codes are just the lower byte in any event.
3758 */
3759 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003760 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003761 /* Indicate failure - this will cause the file object
3762 * to raise an I/O error and translate the last Win32
3763 * error code from errno. We do have a problem with
3764 * last errors that overlap the normal errno table,
3765 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003766 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003767 if (result != EOF) {
3768 /* If the error wasn't from the fclose(), then
3769 * set errno for the file object error handling.
3770 */
3771 errno = GetLastError();
3772 }
3773 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003774 }
3775
3776 /* Free up the native handle at this point */
3777 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003778 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003779
Mark Hammondb37a3732000-08-14 04:47:33 +00003780 /* Remove this file pointer from dictionary */
3781 PyDict_DelItem(_PyPopenProcs, fileObj);
3782
3783 if (PyDict_Size(_PyPopenProcs) == 0) {
3784 Py_DECREF(_PyPopenProcs);
3785 _PyPopenProcs = NULL;
3786 }
3787
3788 } /* if object retrieval ok */
3789
3790 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003791 } /* if _PyPopenProcs */
3792
Tim Peters736aa322000-09-01 06:51:24 +00003793#ifdef WITH_THREAD
3794 /* Tear down the thread & interpreter states.
3795 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003796 * call the thread clear & delete functions, and indeed insist on
3797 * doing that themselves. The lock must be held during the clear, but
3798 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003799 */
3800 PyInterpreterState_Clear(pInterpreterState);
3801 PyEval_ReleaseThread(pThreadState);
3802 PyInterpreterState_Delete(pInterpreterState);
3803#endif
3804
Fredrik Lundh56055a42000-07-23 19:47:12 +00003805 return result;
3806}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003807
3808#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003810posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003811{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003812 char *name;
3813 char *mode = "r";
3814 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003815 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003816 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003817 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003818 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003819 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003820 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003821 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003822 if (fp == NULL)
3823 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003824 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003825 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003826 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003827 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003828}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003829
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003830#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003831#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003832
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003833
Guido van Rossumb6775db1994-08-01 11:34:53 +00003834#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003835static char posix_setuid__doc__[] =
3836"setuid(uid) -> None\n\
3837Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003838static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003839posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003840{
3841 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003842 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003843 return NULL;
3844 if (setuid(uid) < 0)
3845 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003846 Py_INCREF(Py_None);
3847 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003848}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003849#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003851
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003852#ifdef HAVE_SETEUID
3853static char posix_seteuid__doc__[] =
3854"seteuid(uid) -> None\n\
3855Set the current process's effective user id.";
3856static PyObject *
3857posix_seteuid (PyObject *self, PyObject *args)
3858{
3859 int euid;
3860 if (!PyArg_ParseTuple(args, "i", &euid)) {
3861 return NULL;
3862 } else if (seteuid(euid) < 0) {
3863 return posix_error();
3864 } else {
3865 Py_INCREF(Py_None);
3866 return Py_None;
3867 }
3868}
3869#endif /* HAVE_SETEUID */
3870
3871#ifdef HAVE_SETEGID
3872static char posix_setegid__doc__[] =
3873"setegid(gid) -> None\n\
3874Set the current process's effective group id.";
3875static PyObject *
3876posix_setegid (PyObject *self, PyObject *args)
3877{
3878 int egid;
3879 if (!PyArg_ParseTuple(args, "i", &egid)) {
3880 return NULL;
3881 } else if (setegid(egid) < 0) {
3882 return posix_error();
3883 } else {
3884 Py_INCREF(Py_None);
3885 return Py_None;
3886 }
3887}
3888#endif /* HAVE_SETEGID */
3889
3890#ifdef HAVE_SETREUID
3891static char posix_setreuid__doc__[] =
3892"seteuid(ruid, euid) -> None\n\
3893Set the current process's real and effective user ids.";
3894static PyObject *
3895posix_setreuid (PyObject *self, PyObject *args)
3896{
3897 int ruid, euid;
3898 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3899 return NULL;
3900 } else if (setreuid(ruid, euid) < 0) {
3901 return posix_error();
3902 } else {
3903 Py_INCREF(Py_None);
3904 return Py_None;
3905 }
3906}
3907#endif /* HAVE_SETREUID */
3908
3909#ifdef HAVE_SETREGID
3910static char posix_setregid__doc__[] =
3911"setegid(rgid, egid) -> None\n\
3912Set the current process's real and effective group ids.";
3913static PyObject *
3914posix_setregid (PyObject *self, PyObject *args)
3915{
3916 int rgid, egid;
3917 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3918 return NULL;
3919 } else if (setregid(rgid, egid) < 0) {
3920 return posix_error();
3921 } else {
3922 Py_INCREF(Py_None);
3923 return Py_None;
3924 }
3925}
3926#endif /* HAVE_SETREGID */
3927
Guido van Rossumb6775db1994-08-01 11:34:53 +00003928#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003929static char posix_setgid__doc__[] =
3930"setgid(gid) -> None\n\
3931Set the current process's group id.";
3932
Barry Warsaw53699e91996-12-10 23:23:01 +00003933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003934posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003935{
3936 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003937 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003938 return NULL;
3939 if (setgid(gid) < 0)
3940 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003941 Py_INCREF(Py_None);
3942 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003943}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003944#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003945
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003946#ifdef HAVE_SETGROUPS
3947static char posix_setgroups__doc__[] =
3948"setgroups(list) -> None\n\
3949Set the groups of the current process to list.";
3950
3951static PyObject *
3952posix_setgroups(PyObject *self, PyObject *args)
3953{
3954 PyObject *groups;
3955 int i, len;
3956 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003957
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003958 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3959 return NULL;
3960 if (!PySequence_Check(groups)) {
3961 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3962 return NULL;
3963 }
3964 len = PySequence_Size(groups);
3965 if (len > MAX_GROUPS) {
3966 PyErr_SetString(PyExc_ValueError, "too many groups");
3967 return NULL;
3968 }
3969 for(i = 0; i < len; i++) {
3970 PyObject *elem;
3971 elem = PySequence_GetItem(groups, i);
3972 if (!elem)
3973 return NULL;
3974 if (!PyInt_Check(elem)) {
3975 PyErr_SetString(PyExc_TypeError,
3976 "groups must be integers");
3977 Py_DECREF(elem);
3978 return NULL;
3979 }
3980 /* XXX: check that value fits into gid_t. */
3981 grouplist[i] = PyInt_AsLong(elem);
3982 Py_DECREF(elem);
3983 }
3984
3985 if (setgroups(len, grouplist) < 0)
3986 return posix_error();
3987 Py_INCREF(Py_None);
3988 return Py_None;
3989}
3990#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003991
Guido van Rossumb6775db1994-08-01 11:34:53 +00003992#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003993static char posix_waitpid__doc__[] =
3994"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003995Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003996
Barry Warsaw53699e91996-12-10 23:23:01 +00003997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003998posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003999{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004000 int pid, options;
4001#ifdef UNION_WAIT
4002 union wait status;
4003#define status_i (status.w_status)
4004#else
4005 int status;
4006#define status_i status
4007#endif
4008 status_i = 0;
4009
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004010 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004011 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004012 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004013 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004014 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004015 if (pid == -1)
4016 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004017 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004018 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004019}
4020
Tim Petersab034fa2002-02-01 11:27:43 +00004021#elif defined(HAVE_CWAIT)
4022
4023/* MS C has a variant of waitpid() that's usable for most purposes. */
4024static char posix_waitpid__doc__[] =
4025"waitpid(pid, options) -> (pid, status << 8)\n"
4026"Wait for completion of a given process. options is ignored on Windows.";
4027
4028static PyObject *
4029posix_waitpid(PyObject *self, PyObject *args)
4030{
4031 int pid, options;
4032 int status;
4033
4034 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4035 return NULL;
4036 Py_BEGIN_ALLOW_THREADS
4037 pid = _cwait(&status, pid, options);
4038 Py_END_ALLOW_THREADS
4039 if (pid == -1)
4040 return posix_error();
4041 else
4042 /* shift the status left a byte so this is more like the
4043 POSIX waitpid */
4044 return Py_BuildValue("ii", pid, status << 8);
4045}
4046#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004047
Guido van Rossumad0ee831995-03-01 10:34:45 +00004048#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004049static char posix_wait__doc__[] =
4050"wait() -> (pid, status)\n\
4051Wait for completion of a child process.";
4052
Barry Warsaw53699e91996-12-10 23:23:01 +00004053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004054posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004055{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004056 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004057#ifdef UNION_WAIT
4058 union wait status;
4059#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004060#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004061 int status;
4062#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004063#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004064 if (!PyArg_ParseTuple(args, ":wait"))
4065 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004066 status_i = 0;
4067 Py_BEGIN_ALLOW_THREADS
4068 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004069 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004070 if (pid == -1)
4071 return posix_error();
4072 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004073 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004074#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004075}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004076#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004078
4079static char posix_lstat__doc__[] =
Fred Drake193a3f62002-03-12 21:38:49 +00004080"lstat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
4081 st_size, st_atime, st_mtime, st_ctime)\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004082Like stat(path), but do not follow symbolic links.";
4083
Barry Warsaw53699e91996-12-10 23:23:01 +00004084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004085posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004086{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004087#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004088 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004089#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004090 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004091#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004092}
4093
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004094
Guido van Rossumb6775db1994-08-01 11:34:53 +00004095#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004096static char posix_readlink__doc__[] =
4097"readlink(path) -> path\n\
4098Return a string representing the path to which the symbolic link points.";
4099
Barry Warsaw53699e91996-12-10 23:23:01 +00004100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004101posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004102{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004103 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004104 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004105 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004106 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004107 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004108 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004109 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004110 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004111 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004112 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004113 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004114}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004115#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004116
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004117
Guido van Rossumb6775db1994-08-01 11:34:53 +00004118#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004119static char posix_symlink__doc__[] =
4120"symlink(src, dst) -> None\n\
4121Create a symbolic link.";
4122
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004123static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004124posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004125{
Mark Hammondef8b6542001-05-13 08:04:26 +00004126 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004127}
4128#endif /* HAVE_SYMLINK */
4129
4130
4131#ifdef HAVE_TIMES
4132#ifndef HZ
4133#define HZ 60 /* Universal constant :-) */
4134#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004135
Guido van Rossumd48f2521997-12-05 22:19:34 +00004136#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4137static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004138system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004139{
4140 ULONG value = 0;
4141
4142 Py_BEGIN_ALLOW_THREADS
4143 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4144 Py_END_ALLOW_THREADS
4145
4146 return value;
4147}
4148
4149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004150posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004151{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004152 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004153 return NULL;
4154
4155 /* Currently Only Uptime is Provided -- Others Later */
4156 return Py_BuildValue("ddddd",
4157 (double)0 /* t.tms_utime / HZ */,
4158 (double)0 /* t.tms_stime / HZ */,
4159 (double)0 /* t.tms_cutime / HZ */,
4160 (double)0 /* t.tms_cstime / HZ */,
4161 (double)system_uptime() / 1000);
4162}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004163#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004165posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004166{
4167 struct tms t;
4168 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004169 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004170 return NULL;
4171 errno = 0;
4172 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004173 if (c == (clock_t) -1)
4174 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004175 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004176 (double)t.tms_utime / HZ,
4177 (double)t.tms_stime / HZ,
4178 (double)t.tms_cutime / HZ,
4179 (double)t.tms_cstime / HZ,
4180 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004181}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004182#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004183#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004184
4185
Guido van Rossum87755a21996-09-07 00:59:43 +00004186#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004187#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004189posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004190{
4191 FILETIME create, exit, kernel, user;
4192 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004193 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004194 return NULL;
4195 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004196 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4197 /* The fields of a FILETIME structure are the hi and lo part
4198 of a 64-bit value expressed in 100 nanosecond units.
4199 1e7 is one second in such units; 1e-7 the inverse.
4200 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4201 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004202 return Py_BuildValue(
4203 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004204 (double)(kernel.dwHighDateTime*429.4967296 +
4205 kernel.dwLowDateTime*1e-7),
4206 (double)(user.dwHighDateTime*429.4967296 +
4207 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004208 (double)0,
4209 (double)0,
4210 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004211}
Guido van Rossum8d665e61996-06-26 18:22:49 +00004212#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004213
4214#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00004215static char posix_times__doc__[] =
4216"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
4217Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004218#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004219
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004220
Guido van Rossumb6775db1994-08-01 11:34:53 +00004221#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004222static char posix_setsid__doc__[] =
4223"setsid() -> None\n\
4224Call the system call setsid().";
4225
Barry Warsaw53699e91996-12-10 23:23:01 +00004226static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004227posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004228{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004229 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004230 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004231 if (setsid() < 0)
4232 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004233 Py_INCREF(Py_None);
4234 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004235}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004236#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004237
Guido van Rossumb6775db1994-08-01 11:34:53 +00004238#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004239static char posix_setpgid__doc__[] =
4240"setpgid(pid, pgrp) -> None\n\
4241Call the system call setpgid().";
4242
Barry Warsaw53699e91996-12-10 23:23:01 +00004243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004244posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004245{
4246 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004247 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004248 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004249 if (setpgid(pid, pgrp) < 0)
4250 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004251 Py_INCREF(Py_None);
4252 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004253}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004254#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004256
Guido van Rossumb6775db1994-08-01 11:34:53 +00004257#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004258static char posix_tcgetpgrp__doc__[] =
4259"tcgetpgrp(fd) -> pgid\n\
4260Return the process group associated with the terminal given by a fd.";
4261
Barry Warsaw53699e91996-12-10 23:23:01 +00004262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004263posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004264{
4265 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004266 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004267 return NULL;
4268 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004269 if (pgid < 0)
4270 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004271 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004272}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004273#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004275
Guido van Rossumb6775db1994-08-01 11:34:53 +00004276#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004277static char posix_tcsetpgrp__doc__[] =
4278"tcsetpgrp(fd, pgid) -> None\n\
4279Set the process group associated with the terminal given by a fd.";
4280
Barry Warsaw53699e91996-12-10 23:23:01 +00004281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004282posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004283{
4284 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004285 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004286 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004287 if (tcsetpgrp(fd, pgid) < 0)
4288 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004289 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004290 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004291}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004292#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004293
Guido van Rossum687dd131993-05-17 08:34:16 +00004294/* Functions acting on file descriptors */
4295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004296static char posix_open__doc__[] =
4297"open(filename, flag [, mode=0777]) -> fd\n\
4298Open a file (for low level IO).";
4299
Barry Warsaw53699e91996-12-10 23:23:01 +00004300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004301posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004302{
Mark Hammondef8b6542001-05-13 08:04:26 +00004303 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004304 int flag;
4305 int mode = 0777;
4306 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004307 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004308 Py_FileSystemDefaultEncoding, &file,
4309 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004310 return NULL;
4311
Barry Warsaw53699e91996-12-10 23:23:01 +00004312 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004313 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004314 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004315 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004316 return posix_error_with_allocated_filename(file);
4317 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004318 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004319}
4320
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004321
4322static char posix_close__doc__[] =
4323"close(fd) -> None\n\
4324Close a file descriptor (for low level IO).";
4325
Barry Warsaw53699e91996-12-10 23:23:01 +00004326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004327posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004328{
4329 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004330 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004331 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004332 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004333 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004334 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004335 if (res < 0)
4336 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004337 Py_INCREF(Py_None);
4338 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004339}
4340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004341
4342static char posix_dup__doc__[] =
4343"dup(fd) -> fd2\n\
4344Return a duplicate of a file descriptor.";
4345
Barry Warsaw53699e91996-12-10 23:23:01 +00004346static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004347posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004348{
4349 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004350 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004351 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004352 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004353 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004354 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004355 if (fd < 0)
4356 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004357 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004358}
4359
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004360
4361static char posix_dup2__doc__[] =
4362"dup2(fd, fd2) -> None\n\
4363Duplicate file descriptor.";
4364
Barry Warsaw53699e91996-12-10 23:23:01 +00004365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004366posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004367{
4368 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004369 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004370 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004371 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004372 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004373 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004374 if (res < 0)
4375 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004376 Py_INCREF(Py_None);
4377 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004378}
4379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004380
4381static char posix_lseek__doc__[] =
4382"lseek(fd, pos, how) -> newpos\n\
4383Set the current position of a file descriptor.";
4384
Barry Warsaw53699e91996-12-10 23:23:01 +00004385static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004386posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004387{
4388 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00004389#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004390 LONG_LONG pos, res;
4391#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004392 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004393#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004394 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004395 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004396 return NULL;
4397#ifdef SEEK_SET
4398 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4399 switch (how) {
4400 case 0: how = SEEK_SET; break;
4401 case 1: how = SEEK_CUR; break;
4402 case 2: how = SEEK_END; break;
4403 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004404#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004405
4406#if !defined(HAVE_LARGEFILE_SUPPORT)
4407 pos = PyInt_AsLong(posobj);
4408#else
4409 pos = PyLong_Check(posobj) ?
4410 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4411#endif
4412 if (PyErr_Occurred())
4413 return NULL;
4414
Barry Warsaw53699e91996-12-10 23:23:01 +00004415 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00004416#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004417 res = _lseeki64(fd, pos, how);
4418#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004419 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004420#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004421 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004422 if (res < 0)
4423 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004424
4425#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004426 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004427#else
4428 return PyLong_FromLongLong(res);
4429#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004430}
4431
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004432
4433static char posix_read__doc__[] =
4434"read(fd, buffersize) -> string\n\
4435Read a file descriptor.";
4436
Barry Warsaw53699e91996-12-10 23:23:01 +00004437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004438posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004439{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004440 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004441 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004442 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004443 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004444 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004445 if (buffer == NULL)
4446 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004447 Py_BEGIN_ALLOW_THREADS
4448 n = read(fd, PyString_AsString(buffer), size);
4449 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004450 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004451 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004452 return posix_error();
4453 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004454 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004455 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004456 return buffer;
4457}
4458
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004459
4460static char posix_write__doc__[] =
4461"write(fd, string) -> byteswritten\n\
4462Write a string to a file descriptor.";
4463
Barry Warsaw53699e91996-12-10 23:23:01 +00004464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004465posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004466{
4467 int fd, size;
4468 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004469 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004470 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004471 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004472 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004473 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004474 if (size < 0)
4475 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004476 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004477}
4478
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004479
4480static char posix_fstat__doc__[]=
4481"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
4482Like stat(), but for an open file descriptor.";
4483
Barry Warsaw53699e91996-12-10 23:23:01 +00004484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004485posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004486{
4487 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004488 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004489 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004490 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004491 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004492 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004493 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004494 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004495 if (res != 0)
4496 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004497
Fred Drake699f3522000-06-29 21:12:41 +00004498 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004499}
4500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004501
4502static char posix_fdopen__doc__[] =
4503"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
4504Return an open file object connected to a file descriptor.";
4505
Barry Warsaw53699e91996-12-10 23:23:01 +00004506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004507posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004508{
Guido van Rossum687dd131993-05-17 08:34:16 +00004509 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004510 char *mode = "r";
4511 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004512 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004513 PyObject *f;
4514 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004515 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004516
Barry Warsaw53699e91996-12-10 23:23:01 +00004517 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004518 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004519 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004520 if (fp == NULL)
4521 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004522 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004523 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004524 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004525 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004526}
4527
Skip Montanaro1517d842000-07-19 14:34:14 +00004528static char posix_isatty__doc__[] =
4529"isatty(fd) -> Boolean\n\
4530Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00004531connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00004532
4533static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004534posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004535{
4536 int fd;
4537 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4538 return NULL;
4539 return Py_BuildValue("i", isatty(fd));
4540}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004541
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004542#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004543static char posix_pipe__doc__[] =
4544"pipe() -> (read_end, write_end)\n\
4545Create a pipe.";
4546
Barry Warsaw53699e91996-12-10 23:23:01 +00004547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004548posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004549{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004550#if defined(PYOS_OS2)
4551 HFILE read, write;
4552 APIRET rc;
4553
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004554 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004555 return NULL;
4556
4557 Py_BEGIN_ALLOW_THREADS
4558 rc = DosCreatePipe( &read, &write, 4096);
4559 Py_END_ALLOW_THREADS
4560 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004561 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004562
4563 return Py_BuildValue("(ii)", read, write);
4564#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00004565#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00004566 int fds[2];
4567 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004568 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004569 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004570 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004571 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004572 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004573 if (res != 0)
4574 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004575 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004576#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00004577 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004578 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004579 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004580 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004581 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004582 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004583 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004584 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004585 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004586 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004587 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4588 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004589 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004590#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004591#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004592}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004593#endif /* HAVE_PIPE */
4594
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004595
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004596#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004597static char posix_mkfifo__doc__[] =
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004598"mkfifo(filename, [, mode=0666]) -> None\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004599Create a FIFO (a POSIX named pipe).";
4600
Barry Warsaw53699e91996-12-10 23:23:01 +00004601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004602posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004603{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004604 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004605 int mode = 0666;
4606 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004607 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004608 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004609 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004610 res = mkfifo(filename, mode);
4611 Py_END_ALLOW_THREADS
4612 if (res < 0)
4613 return posix_error();
4614 Py_INCREF(Py_None);
4615 return Py_None;
4616}
4617#endif
4618
4619
4620#ifdef HAVE_MKNOD
4621static char posix_mknod__doc__[] =
4622"mknod(filename, [, mode=0600, major, minor]) -> None\n\
4623Create a filesystem node (file, device special file or named pipe)\n\
4624named filename. mode specifies both the permissions to use and the\n\
4625type of node to be created, being combined (bitwise OR) with one of\n\
4626S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4627major and minor define the newly created device special file, otherwise\n\
4628they are ignored.";
4629
4630
4631static PyObject *
4632posix_mknod(PyObject *self, PyObject *args)
4633{
4634 char *filename;
4635 int mode = 0600;
4636 int major = 0;
4637 int minor = 0;
4638 int res;
4639 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4640 &mode, &major, &minor))
4641 return NULL;
4642 Py_BEGIN_ALLOW_THREADS
4643 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004644 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004645 if (res < 0)
4646 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004647 Py_INCREF(Py_None);
4648 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004649}
4650#endif
4651
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004652
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004653#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004654static char posix_ftruncate__doc__[] =
4655"ftruncate(fd, length) -> None\n\
4656Truncate a file to a specified length.";
4657
Barry Warsaw53699e91996-12-10 23:23:01 +00004658static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004659posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004660{
4661 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004662 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004663 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004664 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004665
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004666 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004667 return NULL;
4668
4669#if !defined(HAVE_LARGEFILE_SUPPORT)
4670 length = PyInt_AsLong(lenobj);
4671#else
4672 length = PyLong_Check(lenobj) ?
4673 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4674#endif
4675 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004676 return NULL;
4677
Barry Warsaw53699e91996-12-10 23:23:01 +00004678 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004679 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004680 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004681 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004682 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004683 return NULL;
4684 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004685 Py_INCREF(Py_None);
4686 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004687}
4688#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004689
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004690#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004691static char posix_putenv__doc__[] =
4692"putenv(key, value) -> None\n\
4693Change or add an environment variable.";
4694
Fred Drake762e2061999-08-26 17:23:54 +00004695/* Save putenv() parameters as values here, so we can collect them when they
4696 * get re-set with another call for the same key. */
4697static PyObject *posix_putenv_garbage;
4698
Tim Peters5aa91602002-01-30 05:46:57 +00004699static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004700posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004701{
4702 char *s1, *s2;
4703 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004704 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004705 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004706
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004707 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004708 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004709
4710#if defined(PYOS_OS2)
4711 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4712 APIRET rc;
4713
4714 if (strlen(s2) == 0) /* If New Value is an Empty String */
4715 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4716
4717 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4718 if (rc != NO_ERROR)
4719 return os2_error(rc);
4720
4721 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4722 APIRET rc;
4723
4724 if (strlen(s2) == 0) /* If New Value is an Empty String */
4725 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4726
4727 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4728 if (rc != NO_ERROR)
4729 return os2_error(rc);
4730 } else {
4731#endif
4732
Fred Drake762e2061999-08-26 17:23:54 +00004733 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004734 len = strlen(s1) + strlen(s2) + 2;
4735 /* len includes space for a trailing \0; the size arg to
4736 PyString_FromStringAndSize does not count that */
4737 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004738 if (newstr == NULL)
4739 return PyErr_NoMemory();
4740 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004741 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004742 if (putenv(new)) {
4743 posix_error();
4744 return NULL;
4745 }
Fred Drake762e2061999-08-26 17:23:54 +00004746 /* Install the first arg and newstr in posix_putenv_garbage;
4747 * this will cause previous value to be collected. This has to
4748 * happen after the real putenv() call because the old value
4749 * was still accessible until then. */
4750 if (PyDict_SetItem(posix_putenv_garbage,
4751 PyTuple_GET_ITEM(args, 0), newstr)) {
4752 /* really not much we can do; just leak */
4753 PyErr_Clear();
4754 }
4755 else {
4756 Py_DECREF(newstr);
4757 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004758
4759#if defined(PYOS_OS2)
4760 }
4761#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004762 Py_INCREF(Py_None);
4763 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004764}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004765#endif /* putenv */
4766
Guido van Rossumc524d952001-10-19 01:31:59 +00004767#ifdef HAVE_UNSETENV
4768static char posix_unsetenv__doc__[] =
4769"unsetenv(key) -> None\n\
4770Delete an environment variable.";
4771
4772static PyObject *
4773posix_unsetenv(PyObject *self, PyObject *args)
4774{
4775 char *s1;
4776
4777 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4778 return NULL;
4779
4780 unsetenv(s1);
4781
4782 /* Remove the key from posix_putenv_garbage;
4783 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004784 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004785 * old value was still accessible until then.
4786 */
4787 if (PyDict_DelItem(posix_putenv_garbage,
4788 PyTuple_GET_ITEM(args, 0))) {
4789 /* really not much we can do; just leak */
4790 PyErr_Clear();
4791 }
4792
4793 Py_INCREF(Py_None);
4794 return Py_None;
4795}
4796#endif /* unsetenv */
4797
Guido van Rossumb6a47161997-09-15 22:54:34 +00004798#ifdef HAVE_STRERROR
4799static char posix_strerror__doc__[] =
4800"strerror(code) -> string\n\
4801Translate an error code to a message string.";
4802
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004803static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004804posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004805{
4806 int code;
4807 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004808 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004809 return NULL;
4810 message = strerror(code);
4811 if (message == NULL) {
4812 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004813 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004814 return NULL;
4815 }
4816 return PyString_FromString(message);
4817}
4818#endif /* strerror */
4819
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004820
Guido van Rossumc9641791998-08-04 15:26:23 +00004821#ifdef HAVE_SYS_WAIT_H
4822
4823#ifdef WIFSTOPPED
4824static char posix_WIFSTOPPED__doc__[] =
4825"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004826Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004827
4828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004829posix_WIFSTOPPED(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:WIFSTOPPED", &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", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004846#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004847}
4848#endif /* WIFSTOPPED */
4849
4850#ifdef WIFSIGNALED
4851static char posix_WIFSIGNALED__doc__[] =
4852"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004853Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004854
4855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004856posix_WIFSIGNALED(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:WIFSIGNALED", &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", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004873#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004874}
4875#endif /* WIFSIGNALED */
4876
4877#ifdef WIFEXITED
4878static char posix_WIFEXITED__doc__[] =
4879"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004880Return true if the process returning 'status' exited using the exit()\n\
4881system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004882
4883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004884posix_WIFEXITED(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:WIFEXITED", &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", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004901#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004902}
4903#endif /* WIFEXITED */
4904
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004905#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004906static char posix_WEXITSTATUS__doc__[] =
4907"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004908Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004909
4910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004911posix_WEXITSTATUS(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:WEXITSTATUS", &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", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004928#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004929}
4930#endif /* WEXITSTATUS */
4931
4932#ifdef WTERMSIG
4933static char posix_WTERMSIG__doc__[] =
4934"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004935Return the signal that terminated the process that provided the 'status'\n\
4936value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004937
4938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004939posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004940{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004941#ifdef UNION_WAIT
4942 union wait status;
4943#define status_i (status.w_status)
4944#else
4945 int status;
4946#define status_i status
4947#endif
4948 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004949
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004950 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004951 {
4952 return NULL;
4953 }
Tim Peters5aa91602002-01-30 05:46:57 +00004954
Guido van Rossumc9641791998-08-04 15:26:23 +00004955 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004956#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004957}
4958#endif /* WTERMSIG */
4959
4960#ifdef WSTOPSIG
4961static char posix_WSTOPSIG__doc__[] =
4962"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004963Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004964
4965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004966posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004967{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004968#ifdef UNION_WAIT
4969 union wait status;
4970#define status_i (status.w_status)
4971#else
4972 int status;
4973#define status_i status
4974#endif
4975 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004976
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004977 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004978 {
4979 return NULL;
4980 }
Tim Peters5aa91602002-01-30 05:46:57 +00004981
Guido van Rossumc9641791998-08-04 15:26:23 +00004982 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004983#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004984}
4985#endif /* WSTOPSIG */
4986
4987#endif /* HAVE_SYS_WAIT_H */
4988
4989
Guido van Rossum94f6f721999-01-06 18:42:14 +00004990#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004991#ifdef _SCO_DS
4992/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4993 needed definitions in sys/statvfs.h */
4994#define _SVID3
4995#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004996#include <sys/statvfs.h>
4997
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004998static PyObject*
4999_pystatvfs_fromstructstatvfs(struct statvfs st) {
5000 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5001 if (v == NULL)
5002 return NULL;
5003
5004#if !defined(HAVE_LARGEFILE_SUPPORT)
5005 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5006 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5007 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5008 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5009 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5010 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5011 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5012 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5013 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5014 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5015#else
5016 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5017 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005018 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005019 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005020 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005021 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5022 PyStructSequence_SET_ITEM(v, 4,
5023 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005024 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005025 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005026 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005027 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005028 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005029 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5030 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5031 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5032#endif
5033
5034 return v;
5035}
5036
Guido van Rossum94f6f721999-01-06 18:42:14 +00005037static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005038"fstatvfs(fd) -> \n\
5039 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005040Perform an fstatvfs system call on the given fd.";
5041
5042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005043posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005044{
5045 int fd, res;
5046 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005047
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005048 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005049 return NULL;
5050 Py_BEGIN_ALLOW_THREADS
5051 res = fstatvfs(fd, &st);
5052 Py_END_ALLOW_THREADS
5053 if (res != 0)
5054 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005055
5056 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005057}
5058#endif /* HAVE_FSTATVFS */
5059
5060
5061#if defined(HAVE_STATVFS)
5062#include <sys/statvfs.h>
5063
5064static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005065"statvfs(path) -> \n\
5066 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00005067Perform a statvfs system call on the given path.";
5068
5069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005070posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005071{
5072 char *path;
5073 int res;
5074 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005075 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005076 return NULL;
5077 Py_BEGIN_ALLOW_THREADS
5078 res = statvfs(path, &st);
5079 Py_END_ALLOW_THREADS
5080 if (res != 0)
5081 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005082
5083 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005084}
5085#endif /* HAVE_STATVFS */
5086
5087
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005088#ifdef HAVE_TEMPNAM
5089static char posix_tempnam__doc__[] = "\
5090tempnam([dir[, prefix]]) -> string\n\
5091Return a unique name for a temporary file.\n\
5092The directory and a short may be specified as strings; they may be omitted\n\
5093or None if not needed.";
5094
5095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005096posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005097{
5098 PyObject *result = NULL;
5099 char *dir = NULL;
5100 char *pfx = NULL;
5101 char *name;
5102
5103 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5104 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005105
5106 if (PyErr_Warn(PyExc_RuntimeWarning,
5107 "tempnam is a potential security risk to your program") < 0)
5108 return NULL;
5109
Fred Drake78b71c22001-07-17 20:37:36 +00005110#ifdef MS_WIN32
5111 name = _tempnam(dir, pfx);
5112#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005113 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005114#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005115 if (name == NULL)
5116 return PyErr_NoMemory();
5117 result = PyString_FromString(name);
5118 free(name);
5119 return result;
5120}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005121#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005122
5123
5124#ifdef HAVE_TMPFILE
5125static char posix_tmpfile__doc__[] = "\
5126tmpfile() -> file object\n\
5127Create a temporary file with no directory entries.";
5128
5129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005130posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005131{
5132 FILE *fp;
5133
5134 if (!PyArg_ParseTuple(args, ":tmpfile"))
5135 return NULL;
5136 fp = tmpfile();
5137 if (fp == NULL)
5138 return posix_error();
5139 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
5140}
5141#endif
5142
5143
5144#ifdef HAVE_TMPNAM
5145static char posix_tmpnam__doc__[] = "\
5146tmpnam() -> string\n\
5147Return a unique name for a temporary file.";
5148
5149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005150posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005151{
5152 char buffer[L_tmpnam];
5153 char *name;
5154
5155 if (!PyArg_ParseTuple(args, ":tmpnam"))
5156 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005157
5158 if (PyErr_Warn(PyExc_RuntimeWarning,
5159 "tmpnam is a potential security risk to your program") < 0)
5160 return NULL;
5161
Greg Wardb48bc172000-03-01 21:51:56 +00005162#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005163 name = tmpnam_r(buffer);
5164#else
5165 name = tmpnam(buffer);
5166#endif
5167 if (name == NULL) {
5168 PyErr_SetObject(PyExc_OSError,
5169 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005170#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005171 "unexpected NULL from tmpnam_r"
5172#else
5173 "unexpected NULL from tmpnam"
5174#endif
5175 ));
5176 return NULL;
5177 }
5178 return PyString_FromString(buffer);
5179}
5180#endif
5181
5182
Fred Drakec9680921999-12-13 16:37:25 +00005183/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5184 * It maps strings representing configuration variable names to
5185 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005186 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005187 * rarely-used constants. There are three separate tables that use
5188 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005189 *
5190 * This code is always included, even if none of the interfaces that
5191 * need it are included. The #if hackery needed to avoid it would be
5192 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005193 */
5194struct constdef {
5195 char *name;
5196 long value;
5197};
5198
Fred Drake12c6e2d1999-12-14 21:25:03 +00005199static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005200conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5201 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005202{
5203 if (PyInt_Check(arg)) {
5204 *valuep = PyInt_AS_LONG(arg);
5205 return 1;
5206 }
5207 if (PyString_Check(arg)) {
5208 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005209 size_t lo = 0;
5210 size_t mid;
5211 size_t hi = tablesize;
5212 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005213 char *confname = PyString_AS_STRING(arg);
5214 while (lo < hi) {
5215 mid = (lo + hi) / 2;
5216 cmp = strcmp(confname, table[mid].name);
5217 if (cmp < 0)
5218 hi = mid;
5219 else if (cmp > 0)
5220 lo = mid + 1;
5221 else {
5222 *valuep = table[mid].value;
5223 return 1;
5224 }
5225 }
5226 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5227 }
5228 else
5229 PyErr_SetString(PyExc_TypeError,
5230 "configuration names must be strings or integers");
5231 return 0;
5232}
5233
5234
5235#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5236static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005237#ifdef _PC_ABI_AIO_XFER_MAX
5238 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5239#endif
5240#ifdef _PC_ABI_ASYNC_IO
5241 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5242#endif
Fred Drakec9680921999-12-13 16:37:25 +00005243#ifdef _PC_ASYNC_IO
5244 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5245#endif
5246#ifdef _PC_CHOWN_RESTRICTED
5247 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5248#endif
5249#ifdef _PC_FILESIZEBITS
5250 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5251#endif
5252#ifdef _PC_LAST
5253 {"PC_LAST", _PC_LAST},
5254#endif
5255#ifdef _PC_LINK_MAX
5256 {"PC_LINK_MAX", _PC_LINK_MAX},
5257#endif
5258#ifdef _PC_MAX_CANON
5259 {"PC_MAX_CANON", _PC_MAX_CANON},
5260#endif
5261#ifdef _PC_MAX_INPUT
5262 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5263#endif
5264#ifdef _PC_NAME_MAX
5265 {"PC_NAME_MAX", _PC_NAME_MAX},
5266#endif
5267#ifdef _PC_NO_TRUNC
5268 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5269#endif
5270#ifdef _PC_PATH_MAX
5271 {"PC_PATH_MAX", _PC_PATH_MAX},
5272#endif
5273#ifdef _PC_PIPE_BUF
5274 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5275#endif
5276#ifdef _PC_PRIO_IO
5277 {"PC_PRIO_IO", _PC_PRIO_IO},
5278#endif
5279#ifdef _PC_SOCK_MAXBUF
5280 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5281#endif
5282#ifdef _PC_SYNC_IO
5283 {"PC_SYNC_IO", _PC_SYNC_IO},
5284#endif
5285#ifdef _PC_VDISABLE
5286 {"PC_VDISABLE", _PC_VDISABLE},
5287#endif
5288};
5289
Fred Drakec9680921999-12-13 16:37:25 +00005290static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005291conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005292{
5293 return conv_confname(arg, valuep, posix_constants_pathconf,
5294 sizeof(posix_constants_pathconf)
5295 / sizeof(struct constdef));
5296}
5297#endif
5298
5299#ifdef HAVE_FPATHCONF
5300static char posix_fpathconf__doc__[] = "\
5301fpathconf(fd, name) -> integer\n\
5302Return the configuration limit name for the file descriptor fd.\n\
5303If there is no limit, return -1.";
5304
5305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005306posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005307{
5308 PyObject *result = NULL;
5309 int name, fd;
5310
Fred Drake12c6e2d1999-12-14 21:25:03 +00005311 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5312 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005313 long limit;
5314
5315 errno = 0;
5316 limit = fpathconf(fd, name);
5317 if (limit == -1 && errno != 0)
5318 posix_error();
5319 else
5320 result = PyInt_FromLong(limit);
5321 }
5322 return result;
5323}
5324#endif
5325
5326
5327#ifdef HAVE_PATHCONF
5328static char posix_pathconf__doc__[] = "\
5329pathconf(path, name) -> integer\n\
5330Return the configuration limit name for the file or directory path.\n\
5331If there is no limit, return -1.";
5332
5333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005334posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005335{
5336 PyObject *result = NULL;
5337 int name;
5338 char *path;
5339
5340 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5341 conv_path_confname, &name)) {
5342 long limit;
5343
5344 errno = 0;
5345 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005346 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005347 if (errno == EINVAL)
5348 /* could be a path or name problem */
5349 posix_error();
5350 else
5351 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005352 }
Fred Drakec9680921999-12-13 16:37:25 +00005353 else
5354 result = PyInt_FromLong(limit);
5355 }
5356 return result;
5357}
5358#endif
5359
5360#ifdef HAVE_CONFSTR
5361static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005362#ifdef _CS_ARCHITECTURE
5363 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5364#endif
5365#ifdef _CS_HOSTNAME
5366 {"CS_HOSTNAME", _CS_HOSTNAME},
5367#endif
5368#ifdef _CS_HW_PROVIDER
5369 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5370#endif
5371#ifdef _CS_HW_SERIAL
5372 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5373#endif
5374#ifdef _CS_INITTAB_NAME
5375 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5376#endif
Fred Drakec9680921999-12-13 16:37:25 +00005377#ifdef _CS_LFS64_CFLAGS
5378 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5379#endif
5380#ifdef _CS_LFS64_LDFLAGS
5381 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5382#endif
5383#ifdef _CS_LFS64_LIBS
5384 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5385#endif
5386#ifdef _CS_LFS64_LINTFLAGS
5387 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5388#endif
5389#ifdef _CS_LFS_CFLAGS
5390 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5391#endif
5392#ifdef _CS_LFS_LDFLAGS
5393 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5394#endif
5395#ifdef _CS_LFS_LIBS
5396 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5397#endif
5398#ifdef _CS_LFS_LINTFLAGS
5399 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5400#endif
Fred Draked86ed291999-12-15 15:34:33 +00005401#ifdef _CS_MACHINE
5402 {"CS_MACHINE", _CS_MACHINE},
5403#endif
Fred Drakec9680921999-12-13 16:37:25 +00005404#ifdef _CS_PATH
5405 {"CS_PATH", _CS_PATH},
5406#endif
Fred Draked86ed291999-12-15 15:34:33 +00005407#ifdef _CS_RELEASE
5408 {"CS_RELEASE", _CS_RELEASE},
5409#endif
5410#ifdef _CS_SRPC_DOMAIN
5411 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5412#endif
5413#ifdef _CS_SYSNAME
5414 {"CS_SYSNAME", _CS_SYSNAME},
5415#endif
5416#ifdef _CS_VERSION
5417 {"CS_VERSION", _CS_VERSION},
5418#endif
Fred Drakec9680921999-12-13 16:37:25 +00005419#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5420 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5421#endif
5422#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5423 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5424#endif
5425#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5426 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5427#endif
5428#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5429 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5430#endif
5431#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5432 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5433#endif
5434#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5435 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5436#endif
5437#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5438 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5439#endif
5440#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5441 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5442#endif
5443#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5444 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5445#endif
5446#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5447 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5448#endif
5449#ifdef _CS_XBS5_LP64_OFF64_LIBS
5450 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5451#endif
5452#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5453 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5454#endif
5455#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5456 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5457#endif
5458#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5459 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5460#endif
5461#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5462 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5463#endif
5464#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5465 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5466#endif
Fred Draked86ed291999-12-15 15:34:33 +00005467#ifdef _MIPS_CS_AVAIL_PROCESSORS
5468 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5469#endif
5470#ifdef _MIPS_CS_BASE
5471 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5472#endif
5473#ifdef _MIPS_CS_HOSTID
5474 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5475#endif
5476#ifdef _MIPS_CS_HW_NAME
5477 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5478#endif
5479#ifdef _MIPS_CS_NUM_PROCESSORS
5480 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5481#endif
5482#ifdef _MIPS_CS_OSREL_MAJ
5483 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5484#endif
5485#ifdef _MIPS_CS_OSREL_MIN
5486 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5487#endif
5488#ifdef _MIPS_CS_OSREL_PATCH
5489 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5490#endif
5491#ifdef _MIPS_CS_OS_NAME
5492 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5493#endif
5494#ifdef _MIPS_CS_OS_PROVIDER
5495 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5496#endif
5497#ifdef _MIPS_CS_PROCESSORS
5498 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5499#endif
5500#ifdef _MIPS_CS_SERIAL
5501 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5502#endif
5503#ifdef _MIPS_CS_VENDOR
5504 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5505#endif
Fred Drakec9680921999-12-13 16:37:25 +00005506};
5507
5508static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005509conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005510{
5511 return conv_confname(arg, valuep, posix_constants_confstr,
5512 sizeof(posix_constants_confstr)
5513 / sizeof(struct constdef));
5514}
5515
5516static char posix_confstr__doc__[] = "\
5517confstr(name) -> string\n\
5518Return a string-valued system configuration variable.";
5519
5520static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005521posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005522{
5523 PyObject *result = NULL;
5524 int name;
5525 char buffer[64];
5526
5527 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5528 int len = confstr(name, buffer, sizeof(buffer));
5529
Fred Drakec9680921999-12-13 16:37:25 +00005530 errno = 0;
5531 if (len == 0) {
5532 if (errno != 0)
5533 posix_error();
5534 else
5535 result = PyString_FromString("");
5536 }
5537 else {
5538 if (len >= sizeof(buffer)) {
5539 result = PyString_FromStringAndSize(NULL, len);
5540 if (result != NULL)
5541 confstr(name, PyString_AS_STRING(result), len+1);
5542 }
5543 else
5544 result = PyString_FromString(buffer);
5545 }
5546 }
5547 return result;
5548}
5549#endif
5550
5551
5552#ifdef HAVE_SYSCONF
5553static struct constdef posix_constants_sysconf[] = {
5554#ifdef _SC_2_CHAR_TERM
5555 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5556#endif
5557#ifdef _SC_2_C_BIND
5558 {"SC_2_C_BIND", _SC_2_C_BIND},
5559#endif
5560#ifdef _SC_2_C_DEV
5561 {"SC_2_C_DEV", _SC_2_C_DEV},
5562#endif
5563#ifdef _SC_2_C_VERSION
5564 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5565#endif
5566#ifdef _SC_2_FORT_DEV
5567 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5568#endif
5569#ifdef _SC_2_FORT_RUN
5570 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5571#endif
5572#ifdef _SC_2_LOCALEDEF
5573 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5574#endif
5575#ifdef _SC_2_SW_DEV
5576 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5577#endif
5578#ifdef _SC_2_UPE
5579 {"SC_2_UPE", _SC_2_UPE},
5580#endif
5581#ifdef _SC_2_VERSION
5582 {"SC_2_VERSION", _SC_2_VERSION},
5583#endif
Fred Draked86ed291999-12-15 15:34:33 +00005584#ifdef _SC_ABI_ASYNCHRONOUS_IO
5585 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5586#endif
5587#ifdef _SC_ACL
5588 {"SC_ACL", _SC_ACL},
5589#endif
Fred Drakec9680921999-12-13 16:37:25 +00005590#ifdef _SC_AIO_LISTIO_MAX
5591 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5592#endif
Fred Drakec9680921999-12-13 16:37:25 +00005593#ifdef _SC_AIO_MAX
5594 {"SC_AIO_MAX", _SC_AIO_MAX},
5595#endif
5596#ifdef _SC_AIO_PRIO_DELTA_MAX
5597 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5598#endif
5599#ifdef _SC_ARG_MAX
5600 {"SC_ARG_MAX", _SC_ARG_MAX},
5601#endif
5602#ifdef _SC_ASYNCHRONOUS_IO
5603 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5604#endif
5605#ifdef _SC_ATEXIT_MAX
5606 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5607#endif
Fred Draked86ed291999-12-15 15:34:33 +00005608#ifdef _SC_AUDIT
5609 {"SC_AUDIT", _SC_AUDIT},
5610#endif
Fred Drakec9680921999-12-13 16:37:25 +00005611#ifdef _SC_AVPHYS_PAGES
5612 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5613#endif
5614#ifdef _SC_BC_BASE_MAX
5615 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5616#endif
5617#ifdef _SC_BC_DIM_MAX
5618 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5619#endif
5620#ifdef _SC_BC_SCALE_MAX
5621 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5622#endif
5623#ifdef _SC_BC_STRING_MAX
5624 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5625#endif
Fred Draked86ed291999-12-15 15:34:33 +00005626#ifdef _SC_CAP
5627 {"SC_CAP", _SC_CAP},
5628#endif
Fred Drakec9680921999-12-13 16:37:25 +00005629#ifdef _SC_CHARCLASS_NAME_MAX
5630 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5631#endif
5632#ifdef _SC_CHAR_BIT
5633 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5634#endif
5635#ifdef _SC_CHAR_MAX
5636 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5637#endif
5638#ifdef _SC_CHAR_MIN
5639 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5640#endif
5641#ifdef _SC_CHILD_MAX
5642 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5643#endif
5644#ifdef _SC_CLK_TCK
5645 {"SC_CLK_TCK", _SC_CLK_TCK},
5646#endif
5647#ifdef _SC_COHER_BLKSZ
5648 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5649#endif
5650#ifdef _SC_COLL_WEIGHTS_MAX
5651 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5652#endif
5653#ifdef _SC_DCACHE_ASSOC
5654 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5655#endif
5656#ifdef _SC_DCACHE_BLKSZ
5657 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5658#endif
5659#ifdef _SC_DCACHE_LINESZ
5660 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5661#endif
5662#ifdef _SC_DCACHE_SZ
5663 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5664#endif
5665#ifdef _SC_DCACHE_TBLKSZ
5666 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5667#endif
5668#ifdef _SC_DELAYTIMER_MAX
5669 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5670#endif
5671#ifdef _SC_EQUIV_CLASS_MAX
5672 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5673#endif
5674#ifdef _SC_EXPR_NEST_MAX
5675 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5676#endif
5677#ifdef _SC_FSYNC
5678 {"SC_FSYNC", _SC_FSYNC},
5679#endif
5680#ifdef _SC_GETGR_R_SIZE_MAX
5681 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5682#endif
5683#ifdef _SC_GETPW_R_SIZE_MAX
5684 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5685#endif
5686#ifdef _SC_ICACHE_ASSOC
5687 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5688#endif
5689#ifdef _SC_ICACHE_BLKSZ
5690 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5691#endif
5692#ifdef _SC_ICACHE_LINESZ
5693 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5694#endif
5695#ifdef _SC_ICACHE_SZ
5696 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5697#endif
Fred Draked86ed291999-12-15 15:34:33 +00005698#ifdef _SC_INF
5699 {"SC_INF", _SC_INF},
5700#endif
Fred Drakec9680921999-12-13 16:37:25 +00005701#ifdef _SC_INT_MAX
5702 {"SC_INT_MAX", _SC_INT_MAX},
5703#endif
5704#ifdef _SC_INT_MIN
5705 {"SC_INT_MIN", _SC_INT_MIN},
5706#endif
5707#ifdef _SC_IOV_MAX
5708 {"SC_IOV_MAX", _SC_IOV_MAX},
5709#endif
Fred Draked86ed291999-12-15 15:34:33 +00005710#ifdef _SC_IP_SECOPTS
5711 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5712#endif
Fred Drakec9680921999-12-13 16:37:25 +00005713#ifdef _SC_JOB_CONTROL
5714 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5715#endif
Fred Draked86ed291999-12-15 15:34:33 +00005716#ifdef _SC_KERN_POINTERS
5717 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5718#endif
5719#ifdef _SC_KERN_SIM
5720 {"SC_KERN_SIM", _SC_KERN_SIM},
5721#endif
Fred Drakec9680921999-12-13 16:37:25 +00005722#ifdef _SC_LINE_MAX
5723 {"SC_LINE_MAX", _SC_LINE_MAX},
5724#endif
5725#ifdef _SC_LOGIN_NAME_MAX
5726 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5727#endif
5728#ifdef _SC_LOGNAME_MAX
5729 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5730#endif
5731#ifdef _SC_LONG_BIT
5732 {"SC_LONG_BIT", _SC_LONG_BIT},
5733#endif
Fred Draked86ed291999-12-15 15:34:33 +00005734#ifdef _SC_MAC
5735 {"SC_MAC", _SC_MAC},
5736#endif
Fred Drakec9680921999-12-13 16:37:25 +00005737#ifdef _SC_MAPPED_FILES
5738 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5739#endif
5740#ifdef _SC_MAXPID
5741 {"SC_MAXPID", _SC_MAXPID},
5742#endif
5743#ifdef _SC_MB_LEN_MAX
5744 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5745#endif
5746#ifdef _SC_MEMLOCK
5747 {"SC_MEMLOCK", _SC_MEMLOCK},
5748#endif
5749#ifdef _SC_MEMLOCK_RANGE
5750 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5751#endif
5752#ifdef _SC_MEMORY_PROTECTION
5753 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5754#endif
5755#ifdef _SC_MESSAGE_PASSING
5756 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5757#endif
Fred Draked86ed291999-12-15 15:34:33 +00005758#ifdef _SC_MMAP_FIXED_ALIGNMENT
5759 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5760#endif
Fred Drakec9680921999-12-13 16:37:25 +00005761#ifdef _SC_MQ_OPEN_MAX
5762 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5763#endif
5764#ifdef _SC_MQ_PRIO_MAX
5765 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5766#endif
Fred Draked86ed291999-12-15 15:34:33 +00005767#ifdef _SC_NACLS_MAX
5768 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5769#endif
Fred Drakec9680921999-12-13 16:37:25 +00005770#ifdef _SC_NGROUPS_MAX
5771 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5772#endif
5773#ifdef _SC_NL_ARGMAX
5774 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5775#endif
5776#ifdef _SC_NL_LANGMAX
5777 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5778#endif
5779#ifdef _SC_NL_MSGMAX
5780 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5781#endif
5782#ifdef _SC_NL_NMAX
5783 {"SC_NL_NMAX", _SC_NL_NMAX},
5784#endif
5785#ifdef _SC_NL_SETMAX
5786 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5787#endif
5788#ifdef _SC_NL_TEXTMAX
5789 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5790#endif
5791#ifdef _SC_NPROCESSORS_CONF
5792 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5793#endif
5794#ifdef _SC_NPROCESSORS_ONLN
5795 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5796#endif
Fred Draked86ed291999-12-15 15:34:33 +00005797#ifdef _SC_NPROC_CONF
5798 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5799#endif
5800#ifdef _SC_NPROC_ONLN
5801 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5802#endif
Fred Drakec9680921999-12-13 16:37:25 +00005803#ifdef _SC_NZERO
5804 {"SC_NZERO", _SC_NZERO},
5805#endif
5806#ifdef _SC_OPEN_MAX
5807 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5808#endif
5809#ifdef _SC_PAGESIZE
5810 {"SC_PAGESIZE", _SC_PAGESIZE},
5811#endif
5812#ifdef _SC_PAGE_SIZE
5813 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5814#endif
5815#ifdef _SC_PASS_MAX
5816 {"SC_PASS_MAX", _SC_PASS_MAX},
5817#endif
5818#ifdef _SC_PHYS_PAGES
5819 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5820#endif
5821#ifdef _SC_PII
5822 {"SC_PII", _SC_PII},
5823#endif
5824#ifdef _SC_PII_INTERNET
5825 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5826#endif
5827#ifdef _SC_PII_INTERNET_DGRAM
5828 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5829#endif
5830#ifdef _SC_PII_INTERNET_STREAM
5831 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5832#endif
5833#ifdef _SC_PII_OSI
5834 {"SC_PII_OSI", _SC_PII_OSI},
5835#endif
5836#ifdef _SC_PII_OSI_CLTS
5837 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5838#endif
5839#ifdef _SC_PII_OSI_COTS
5840 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5841#endif
5842#ifdef _SC_PII_OSI_M
5843 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5844#endif
5845#ifdef _SC_PII_SOCKET
5846 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5847#endif
5848#ifdef _SC_PII_XTI
5849 {"SC_PII_XTI", _SC_PII_XTI},
5850#endif
5851#ifdef _SC_POLL
5852 {"SC_POLL", _SC_POLL},
5853#endif
5854#ifdef _SC_PRIORITIZED_IO
5855 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5856#endif
5857#ifdef _SC_PRIORITY_SCHEDULING
5858 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5859#endif
5860#ifdef _SC_REALTIME_SIGNALS
5861 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5862#endif
5863#ifdef _SC_RE_DUP_MAX
5864 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5865#endif
5866#ifdef _SC_RTSIG_MAX
5867 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5868#endif
5869#ifdef _SC_SAVED_IDS
5870 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5871#endif
5872#ifdef _SC_SCHAR_MAX
5873 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5874#endif
5875#ifdef _SC_SCHAR_MIN
5876 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5877#endif
5878#ifdef _SC_SELECT
5879 {"SC_SELECT", _SC_SELECT},
5880#endif
5881#ifdef _SC_SEMAPHORES
5882 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5883#endif
5884#ifdef _SC_SEM_NSEMS_MAX
5885 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5886#endif
5887#ifdef _SC_SEM_VALUE_MAX
5888 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5889#endif
5890#ifdef _SC_SHARED_MEMORY_OBJECTS
5891 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5892#endif
5893#ifdef _SC_SHRT_MAX
5894 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5895#endif
5896#ifdef _SC_SHRT_MIN
5897 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5898#endif
5899#ifdef _SC_SIGQUEUE_MAX
5900 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5901#endif
5902#ifdef _SC_SIGRT_MAX
5903 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5904#endif
5905#ifdef _SC_SIGRT_MIN
5906 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5907#endif
Fred Draked86ed291999-12-15 15:34:33 +00005908#ifdef _SC_SOFTPOWER
5909 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5910#endif
Fred Drakec9680921999-12-13 16:37:25 +00005911#ifdef _SC_SPLIT_CACHE
5912 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5913#endif
5914#ifdef _SC_SSIZE_MAX
5915 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5916#endif
5917#ifdef _SC_STACK_PROT
5918 {"SC_STACK_PROT", _SC_STACK_PROT},
5919#endif
5920#ifdef _SC_STREAM_MAX
5921 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5922#endif
5923#ifdef _SC_SYNCHRONIZED_IO
5924 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5925#endif
5926#ifdef _SC_THREADS
5927 {"SC_THREADS", _SC_THREADS},
5928#endif
5929#ifdef _SC_THREAD_ATTR_STACKADDR
5930 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5931#endif
5932#ifdef _SC_THREAD_ATTR_STACKSIZE
5933 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5934#endif
5935#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5936 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5937#endif
5938#ifdef _SC_THREAD_KEYS_MAX
5939 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5940#endif
5941#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5942 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5943#endif
5944#ifdef _SC_THREAD_PRIO_INHERIT
5945 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5946#endif
5947#ifdef _SC_THREAD_PRIO_PROTECT
5948 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5949#endif
5950#ifdef _SC_THREAD_PROCESS_SHARED
5951 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5952#endif
5953#ifdef _SC_THREAD_SAFE_FUNCTIONS
5954 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5955#endif
5956#ifdef _SC_THREAD_STACK_MIN
5957 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5958#endif
5959#ifdef _SC_THREAD_THREADS_MAX
5960 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5961#endif
5962#ifdef _SC_TIMERS
5963 {"SC_TIMERS", _SC_TIMERS},
5964#endif
5965#ifdef _SC_TIMER_MAX
5966 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5967#endif
5968#ifdef _SC_TTY_NAME_MAX
5969 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5970#endif
5971#ifdef _SC_TZNAME_MAX
5972 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5973#endif
5974#ifdef _SC_T_IOV_MAX
5975 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5976#endif
5977#ifdef _SC_UCHAR_MAX
5978 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5979#endif
5980#ifdef _SC_UINT_MAX
5981 {"SC_UINT_MAX", _SC_UINT_MAX},
5982#endif
5983#ifdef _SC_UIO_MAXIOV
5984 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5985#endif
5986#ifdef _SC_ULONG_MAX
5987 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5988#endif
5989#ifdef _SC_USHRT_MAX
5990 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5991#endif
5992#ifdef _SC_VERSION
5993 {"SC_VERSION", _SC_VERSION},
5994#endif
5995#ifdef _SC_WORD_BIT
5996 {"SC_WORD_BIT", _SC_WORD_BIT},
5997#endif
5998#ifdef _SC_XBS5_ILP32_OFF32
5999 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6000#endif
6001#ifdef _SC_XBS5_ILP32_OFFBIG
6002 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6003#endif
6004#ifdef _SC_XBS5_LP64_OFF64
6005 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6006#endif
6007#ifdef _SC_XBS5_LPBIG_OFFBIG
6008 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6009#endif
6010#ifdef _SC_XOPEN_CRYPT
6011 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6012#endif
6013#ifdef _SC_XOPEN_ENH_I18N
6014 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6015#endif
6016#ifdef _SC_XOPEN_LEGACY
6017 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6018#endif
6019#ifdef _SC_XOPEN_REALTIME
6020 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6021#endif
6022#ifdef _SC_XOPEN_REALTIME_THREADS
6023 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6024#endif
6025#ifdef _SC_XOPEN_SHM
6026 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6027#endif
6028#ifdef _SC_XOPEN_UNIX
6029 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6030#endif
6031#ifdef _SC_XOPEN_VERSION
6032 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6033#endif
6034#ifdef _SC_XOPEN_XCU_VERSION
6035 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6036#endif
6037#ifdef _SC_XOPEN_XPG2
6038 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6039#endif
6040#ifdef _SC_XOPEN_XPG3
6041 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6042#endif
6043#ifdef _SC_XOPEN_XPG4
6044 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6045#endif
6046};
6047
6048static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006049conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006050{
6051 return conv_confname(arg, valuep, posix_constants_sysconf,
6052 sizeof(posix_constants_sysconf)
6053 / sizeof(struct constdef));
6054}
6055
6056static char posix_sysconf__doc__[] = "\
6057sysconf(name) -> integer\n\
6058Return an integer-valued system configuration variable.";
6059
6060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006061posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006062{
6063 PyObject *result = NULL;
6064 int name;
6065
6066 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6067 int value;
6068
6069 errno = 0;
6070 value = sysconf(name);
6071 if (value == -1 && errno != 0)
6072 posix_error();
6073 else
6074 result = PyInt_FromLong(value);
6075 }
6076 return result;
6077}
6078#endif
6079
6080
Fred Drakebec628d1999-12-15 18:31:10 +00006081/* This code is used to ensure that the tables of configuration value names
6082 * are in sorted order as required by conv_confname(), and also to build the
6083 * the exported dictionaries that are used to publish information about the
6084 * names available on the host platform.
6085 *
6086 * Sorting the table at runtime ensures that the table is properly ordered
6087 * when used, even for platforms we're not able to test on. It also makes
6088 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006089 */
Fred Drakebec628d1999-12-15 18:31:10 +00006090
6091static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006092cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006093{
6094 const struct constdef *c1 =
6095 (const struct constdef *) v1;
6096 const struct constdef *c2 =
6097 (const struct constdef *) v2;
6098
6099 return strcmp(c1->name, c2->name);
6100}
6101
6102static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006103setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006104 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006105{
Fred Drakebec628d1999-12-15 18:31:10 +00006106 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006107 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006108
6109 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6110 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006111 if (d == NULL)
6112 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006113
Barry Warsaw3155db32000-04-13 15:20:40 +00006114 for (i=0; i < tablesize; ++i) {
6115 PyObject *o = PyInt_FromLong(table[i].value);
6116 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6117 Py_XDECREF(o);
6118 Py_DECREF(d);
6119 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006120 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006121 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006122 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006123 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006124}
6125
Fred Drakebec628d1999-12-15 18:31:10 +00006126/* Return -1 on failure, 0 on success. */
6127static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006128setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006129{
6130#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006131 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006132 sizeof(posix_constants_pathconf)
6133 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006134 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006135 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006136#endif
6137#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006138 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006139 sizeof(posix_constants_confstr)
6140 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006141 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006142 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006143#endif
6144#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006145 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006146 sizeof(posix_constants_sysconf)
6147 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006148 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006149 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006150#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006151 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006152}
Fred Draked86ed291999-12-15 15:34:33 +00006153
6154
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006155static char posix_abort__doc__[] = "\
6156abort() -> does not return!\n\
6157Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
6158in the hardest way possible on the hosting operating system.";
6159
6160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006161posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006162{
6163 if (!PyArg_ParseTuple(args, ":abort"))
6164 return NULL;
6165 abort();
6166 /*NOTREACHED*/
6167 Py_FatalError("abort() called from Python code didn't abort!");
6168 return NULL;
6169}
Fred Drakebec628d1999-12-15 18:31:10 +00006170
Tim Petersf58a7aa2000-09-22 10:05:54 +00006171#ifdef MS_WIN32
6172static char win32_startfile__doc__[] = "\
6173startfile(filepath) - Start a file with its associated application.\n\
6174\n\
6175This acts like double-clicking the file in Explorer, or giving the file\n\
6176name as an argument to the DOS \"start\" command: the file is opened\n\
6177with whatever application (if any) its extension is associated.\n\
6178\n\
6179startfile returns as soon as the associated application is launched.\n\
6180There is no option to wait for the application to close, and no way\n\
6181to retrieve the application's exit status.\n\
6182\n\
6183The filepath is relative to the current directory. If you want to use\n\
6184an absolute path, make sure the first character is not a slash (\"/\");\n\
6185the underlying Win32 ShellExecute function doesn't work if it is.";
6186
6187static PyObject *
6188win32_startfile(PyObject *self, PyObject *args)
6189{
6190 char *filepath;
6191 HINSTANCE rc;
6192 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6193 return NULL;
6194 Py_BEGIN_ALLOW_THREADS
6195 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6196 Py_END_ALLOW_THREADS
6197 if (rc <= (HINSTANCE)32)
6198 return win32_error("startfile", filepath);
6199 Py_INCREF(Py_None);
6200 return Py_None;
6201}
6202#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006203
6204static PyMethodDef posix_methods[] = {
6205 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6206#ifdef HAVE_TTYNAME
6207 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6208#endif
6209 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6210 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006211#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006212 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006213#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006214#ifdef HAVE_CHROOT
6215 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6216#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006217#ifdef HAVE_CTERMID
6218 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6219#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006220#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006221 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006222#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006223#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006224 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006225#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006226 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6227 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6228 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006229#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006230 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006231#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006232#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006233 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006234#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006235 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6236 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6237 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006238#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006239 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006240#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006241#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006242 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006243#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006244 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006245#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006246 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006247#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006248 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6249 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6250 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006251#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006252 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006253#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006254 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006255#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006256 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6257 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006258#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006259#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006260 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6261 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006262#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006263#ifdef HAVE_FORK1
6264 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6265#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006266#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006267 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006268#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006269#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006270 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006271#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006272#ifdef HAVE_FORKPTY
6273 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6274#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006275#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006276 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006277#endif /* HAVE_GETEGID */
6278#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006279 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006280#endif /* HAVE_GETEUID */
6281#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006282 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006283#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006284#ifdef HAVE_GETGROUPS
6285 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6286#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006287 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006288#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006289 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006290#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006291#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006292 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006293#endif /* HAVE_GETPPID */
6294#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006295 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006296#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006297#ifdef HAVE_GETLOGIN
6298 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6299#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006300#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006301 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006302#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006303#ifdef HAVE_KILLPG
6304 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6305#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006306#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006307 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006308#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006309#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006310 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006311#ifdef MS_WIN32
6312 {"popen2", win32_popen2, METH_VARARGS},
6313 {"popen3", win32_popen3, METH_VARARGS},
6314 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006315 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006316#else
6317#if defined(PYOS_OS2) && defined(PYCC_GCC)
6318 {"popen2", os2emx_popen2, METH_VARARGS},
6319 {"popen3", os2emx_popen3, METH_VARARGS},
6320 {"popen4", os2emx_popen4, METH_VARARGS},
6321#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006322#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006323#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006324#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006325 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006326#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006327#ifdef HAVE_SETEUID
6328 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6329#endif /* HAVE_SETEUID */
6330#ifdef HAVE_SETEGID
6331 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6332#endif /* HAVE_SETEGID */
6333#ifdef HAVE_SETREUID
6334 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6335#endif /* HAVE_SETREUID */
6336#ifdef HAVE_SETREGID
6337 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6338#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006339#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006340 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006341#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006342#ifdef HAVE_SETGROUPS
6343 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6344#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006345#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006346 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006347#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006348#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006349 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006350#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006351#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006352 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006353#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006354#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006355 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006356#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006357#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006358 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006359#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006360#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006361 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006362#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006363#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006364 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006365#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006366 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6367 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6368 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6369 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6370 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6371 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6372 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6373 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6374 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006375 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006376#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006377 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006378#endif
6379#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006380 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006381#endif
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006382#ifdef HAVE_MKNOD
6383 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6384#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006385#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006386 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006387#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006388#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006389 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006390#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006391#ifdef HAVE_UNSETENV
6392 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6393#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006394#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006395 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006396#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006397#ifdef HAVE_FCHDIR
6398 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6399#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006400#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006401 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006402#endif
6403#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006404 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006405#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006406#ifdef HAVE_SYS_WAIT_H
6407#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006408 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006409#endif /* WIFSTOPPED */
6410#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006411 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006412#endif /* WIFSIGNALED */
6413#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006414 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006415#endif /* WIFEXITED */
6416#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006417 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006418#endif /* WEXITSTATUS */
6419#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006420 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006421#endif /* WTERMSIG */
6422#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006423 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006424#endif /* WSTOPSIG */
6425#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006426#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006427 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006428#endif
6429#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006430 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006431#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006432#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006433 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6434#endif
6435#ifdef HAVE_TEMPNAM
6436 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6437#endif
6438#ifdef HAVE_TMPNAM
6439 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6440#endif
Fred Drakec9680921999-12-13 16:37:25 +00006441#ifdef HAVE_CONFSTR
6442 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6443#endif
6444#ifdef HAVE_SYSCONF
6445 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6446#endif
6447#ifdef HAVE_FPATHCONF
6448 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6449#endif
6450#ifdef HAVE_PATHCONF
6451 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6452#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006453 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00006454#ifdef MS_WIN32
6455 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6456#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006457 {NULL, NULL} /* Sentinel */
6458};
6459
6460
Barry Warsaw4a342091996-12-19 23:50:02 +00006461static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006462ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006463{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006464 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006465}
6466
Guido van Rossumd48f2521997-12-05 22:19:34 +00006467#if defined(PYOS_OS2)
6468/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006469static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006470{
6471 APIRET rc;
6472 ULONG values[QSV_MAX+1];
6473 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006474 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006475
6476 Py_BEGIN_ALLOW_THREADS
6477 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6478 Py_END_ALLOW_THREADS
6479
6480 if (rc != NO_ERROR) {
6481 os2_error(rc);
6482 return -1;
6483 }
6484
Fred Drake4d1e64b2002-04-15 19:40:07 +00006485 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6486 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6487 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6488 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6489 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6490 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6491 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006492
6493 switch (values[QSV_VERSION_MINOR]) {
6494 case 0: ver = "2.00"; break;
6495 case 10: ver = "2.10"; break;
6496 case 11: ver = "2.11"; break;
6497 case 30: ver = "3.00"; break;
6498 case 40: ver = "4.00"; break;
6499 case 50: ver = "5.00"; break;
6500 default:
Tim Peters885d4572001-11-28 20:27:42 +00006501 PyOS_snprintf(tmp, sizeof(tmp),
6502 "%d-%d", values[QSV_VERSION_MAJOR],
6503 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006504 ver = &tmp[0];
6505 }
6506
6507 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006508 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006509 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006510
6511 /* Add Indicator of Which Drive was Used to Boot the System */
6512 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6513 tmp[1] = ':';
6514 tmp[2] = '\0';
6515
Fred Drake4d1e64b2002-04-15 19:40:07 +00006516 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006517}
6518#endif
6519
Barry Warsaw4a342091996-12-19 23:50:02 +00006520static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006521all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006522{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006523#ifdef F_OK
6524 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006525#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006526#ifdef R_OK
6527 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006528#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006529#ifdef W_OK
6530 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006531#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006532#ifdef X_OK
6533 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006534#endif
Fred Drakec9680921999-12-13 16:37:25 +00006535#ifdef NGROUPS_MAX
6536 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6537#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006538#ifdef TMP_MAX
6539 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6540#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006541#ifdef WNOHANG
6542 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006543#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006544#ifdef O_RDONLY
6545 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6546#endif
6547#ifdef O_WRONLY
6548 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6549#endif
6550#ifdef O_RDWR
6551 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6552#endif
6553#ifdef O_NDELAY
6554 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6555#endif
6556#ifdef O_NONBLOCK
6557 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6558#endif
6559#ifdef O_APPEND
6560 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6561#endif
6562#ifdef O_DSYNC
6563 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6564#endif
6565#ifdef O_RSYNC
6566 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6567#endif
6568#ifdef O_SYNC
6569 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6570#endif
6571#ifdef O_NOCTTY
6572 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6573#endif
6574#ifdef O_CREAT
6575 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6576#endif
6577#ifdef O_EXCL
6578 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6579#endif
6580#ifdef O_TRUNC
6581 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6582#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006583#ifdef O_BINARY
6584 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6585#endif
6586#ifdef O_TEXT
6587 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6588#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006589#ifdef O_LARGEFILE
6590 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6591#endif
6592
Tim Peters5aa91602002-01-30 05:46:57 +00006593/* MS Windows */
6594#ifdef O_NOINHERIT
6595 /* Don't inherit in child processes. */
6596 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6597#endif
6598#ifdef _O_SHORT_LIVED
6599 /* Optimize for short life (keep in memory). */
6600 /* MS forgot to define this one with a non-underscore form too. */
6601 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6602#endif
6603#ifdef O_TEMPORARY
6604 /* Automatically delete when last handle is closed. */
6605 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6606#endif
6607#ifdef O_RANDOM
6608 /* Optimize for random access. */
6609 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6610#endif
6611#ifdef O_SEQUENTIAL
6612 /* Optimize for sequential access. */
6613 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6614#endif
6615
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006616/* GNU extensions. */
6617#ifdef O_DIRECT
6618 /* Direct disk access. */
6619 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6620#endif
6621#ifdef O_DIRECTORY
6622 /* Must be a directory. */
6623 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6624#endif
6625#ifdef O_NOFOLLOW
6626 /* Do not follow links. */
6627 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6628#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006629
Guido van Rossum246bc171999-02-01 23:54:31 +00006630#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006631#if defined(PYOS_OS2) && defined(PYCC_GCC)
6632 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6633 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6634 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6635 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6636 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6637 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6638 if (ins(d, "P_PM", (long)P_PM)) return -1;
6639 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6640 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6641 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6642 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6643 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6644 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6645 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6646 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6647 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6648 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6649 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6650 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6651 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6652#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006653 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6654 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6655 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6656 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6657 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006658#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006659#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006660
Guido van Rossumd48f2521997-12-05 22:19:34 +00006661#if defined(PYOS_OS2)
6662 if (insertvalues(d)) return -1;
6663#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006664 return 0;
6665}
6666
6667
Tim Peters5aa91602002-01-30 05:46:57 +00006668#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006669#define INITFUNC initnt
6670#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006671
6672#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006673#define INITFUNC initos2
6674#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006675
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006676#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006677#define INITFUNC initposix
6678#define MODNAME "posix"
6679#endif
6680
Guido van Rossum3886bb61998-12-04 18:50:17 +00006681DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006682INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006683{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006684 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006685
Fred Drake4d1e64b2002-04-15 19:40:07 +00006686 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006687 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006688 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006689
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006690 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006691 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006692 Py_XINCREF(v);
6693 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006694 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006695 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006696
Fred Drake4d1e64b2002-04-15 19:40:07 +00006697 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006698 return;
6699
Fred Drake4d1e64b2002-04-15 19:40:07 +00006700 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006701 return;
6702
Fred Drake4d1e64b2002-04-15 19:40:07 +00006703 Py_INCREF(PyExc_OSError);
6704 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006705
Guido van Rossumb3d39562000-01-31 18:41:26 +00006706#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006707 if (posix_putenv_garbage == NULL)
6708 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006709#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006710
Guido van Rossum14648392001-12-08 18:02:58 +00006711 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006712 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006713 Py_INCREF((PyObject*) &StatResultType);
6714 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006715
Guido van Rossum14648392001-12-08 18:02:58 +00006716 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006717 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006718 Py_INCREF((PyObject*) &StatVFSResultType);
6719 PyModule_AddObject(m, "statvfs_result",
6720 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006721}