blob: a7a7ddd3988c51754365357b2635fa2b87bbbbae [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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
19PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000020"This module provides access to operating system functionality that is\n\
21standardized by the C Standard and the POSIX standard (a thinly\n\
22disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023corresponding Unix manual entries for more information on calls.");
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
Neal Norwitz3d949422002-04-20 13:46:43 +0000281#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
282#include <sys/mkdev.h>
283#endif
Fred Drake699f3522000-06-29 21:12:41 +0000284
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285/* Return a dictionary corresponding to the POSIX environment table */
286
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000289#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290
Barry Warsaw53699e91996-12-10 23:23:01 +0000291static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000292convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293{
Barry Warsaw53699e91996-12-10 23:23:01 +0000294 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000296 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 if (d == NULL)
298 return NULL;
299 if (environ == NULL)
300 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000301 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000303 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000304 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000305 char *p = strchr(*e, '=');
306 if (p == NULL)
307 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000308 k = PyString_FromStringAndSize(*e, (int)(p-*e));
309 if (k == NULL) {
310 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000312 }
313 v = PyString_FromString(p+1);
314 if (v == NULL) {
315 PyErr_Clear();
316 Py_DECREF(k);
317 continue;
318 }
319 if (PyDict_GetItem(d, k) == NULL) {
320 if (PyDict_SetItem(d, k, v) != 0)
321 PyErr_Clear();
322 }
323 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000324 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000326#if defined(PYOS_OS2)
327 {
328 APIRET rc;
329 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
330
331 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000332 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000333 PyObject *v = PyString_FromString(buffer);
334 PyDict_SetItemString(d, "BEGINLIBPATH", v);
335 Py_DECREF(v);
336 }
337 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
338 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
339 PyObject *v = PyString_FromString(buffer);
340 PyDict_SetItemString(d, "ENDLIBPATH", v);
341 Py_DECREF(v);
342 }
343 }
344#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 return d;
346}
347
348
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349/* Set a POSIX-specific error from errno, and return NULL */
350
Barry Warsawd58d7641998-07-23 16:14:40 +0000351static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000352posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000353{
Barry Warsawca74da41999-02-09 19:31:45 +0000354 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000355}
Barry Warsawd58d7641998-07-23 16:14:40 +0000356static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000357posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000358{
Barry Warsawca74da41999-02-09 19:31:45 +0000359 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000360}
361
Mark Hammondef8b6542001-05-13 08:04:26 +0000362static PyObject *
363posix_error_with_allocated_filename(char* name)
364{
365 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
366 PyMem_Free(name);
367 return rc;
368}
369
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000370#ifdef MS_WIN32
371static PyObject *
372win32_error(char* function, char* filename)
373{
Mark Hammond33a6da92000-08-15 00:46:38 +0000374 /* XXX We should pass the function name along in the future.
375 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000376 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000377 Windows error object, which is non-trivial.
378 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000379 errno = GetLastError();
380 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000381 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000382 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000383 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000384}
385#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000386
Guido van Rossumd48f2521997-12-05 22:19:34 +0000387#if defined(PYOS_OS2)
388/**********************************************************************
389 * Helper Function to Trim and Format OS/2 Messages
390 **********************************************************************/
391 static void
392os2_formatmsg(char *msgbuf, int msglen, char *reason)
393{
394 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
395
396 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
397 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
398
399 while (lastc > msgbuf && isspace(*lastc))
400 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
401 }
402
403 /* Add Optional Reason Text */
404 if (reason) {
405 strcat(msgbuf, " : ");
406 strcat(msgbuf, reason);
407 }
408}
409
410/**********************************************************************
411 * Decode an OS/2 Operating System Error Code
412 *
413 * A convenience function to lookup an OS/2 error code and return a
414 * text message we can use to raise a Python exception.
415 *
416 * Notes:
417 * The messages for errors returned from the OS/2 kernel reside in
418 * the file OSO001.MSG in the \OS2 directory hierarchy.
419 *
420 **********************************************************************/
421 static char *
422os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
423{
424 APIRET rc;
425 ULONG msglen;
426
427 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
428 Py_BEGIN_ALLOW_THREADS
429 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
430 errorcode, "oso001.msg", &msglen);
431 Py_END_ALLOW_THREADS
432
433 if (rc == NO_ERROR)
434 os2_formatmsg(msgbuf, msglen, reason);
435 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000436 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000437 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000438
439 return msgbuf;
440}
441
442/* Set an OS/2-specific error and return NULL. OS/2 kernel
443 errors are not in a global variable e.g. 'errno' nor are
444 they congruent with posix error numbers. */
445
446static PyObject * os2_error(int code)
447{
448 char text[1024];
449 PyObject *v;
450
451 os2_strerror(text, sizeof(text), code, "");
452
453 v = Py_BuildValue("(is)", code, text);
454 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000455 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000456 Py_DECREF(v);
457 }
458 return NULL; /* Signal to Python that an Exception is Pending */
459}
460
461#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000462
463/* POSIX generic methods */
464
Barry Warsaw53699e91996-12-10 23:23:01 +0000465static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000466posix_fildes(PyObject *fdobj, int (*func)(int))
467{
468 int fd;
469 int res;
470 fd = PyObject_AsFileDescriptor(fdobj);
471 if (fd < 0)
472 return NULL;
473 Py_BEGIN_ALLOW_THREADS
474 res = (*func)(fd);
475 Py_END_ALLOW_THREADS
476 if (res < 0)
477 return posix_error();
478 Py_INCREF(Py_None);
479 return Py_None;
480}
Guido van Rossum21142a01999-01-08 21:05:37 +0000481
482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000483posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000484{
Mark Hammondef8b6542001-05-13 08:04:26 +0000485 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000486 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000487 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000488 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000490 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000491 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000492 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000493 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000494 return posix_error_with_allocated_filename(path1);
495 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000496 Py_INCREF(Py_None);
497 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000498}
499
Barry Warsaw53699e91996-12-10 23:23:01 +0000500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000501posix_2str(PyObject *args, char *format,
502 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000503{
Mark Hammondef8b6542001-05-13 08:04:26 +0000504 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000505 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000506 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000507 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000508 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000510 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000511 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000512 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000513 PyMem_Free(path1);
514 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000515 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000516 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000518 Py_INCREF(Py_None);
519 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000520}
521
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000522PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000523"stat_result: Result from stat or lstat.\n\n\
524This object may be accessed either as a tuple of\n\
525 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
526or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
527\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000528Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000529they are available as attributes only.\n\
530\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000531See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000532
533static PyStructSequence_Field stat_result_fields[] = {
534 {"st_mode", "protection bits"},
535 {"st_ino", "inode"},
536 {"st_dev", "device"},
537 {"st_nlink", "number of hard links"},
538 {"st_uid", "user ID of owner"},
539 {"st_gid", "group ID of owner"},
540 {"st_size", "total size, in bytes"},
541 {"st_atime", "time of last access"},
542 {"st_mtime", "time of last modification"},
543 {"st_ctime", "time of last change"},
544#ifdef HAVE_ST_BLKSIZE
545 {"st_blksize", "blocksize for filesystem I/O"},
546#endif
547#ifdef HAVE_ST_BLOCKS
548 {"st_blocks", "number of blocks allocated"},
549#endif
550#ifdef HAVE_ST_RDEV
551 {"st_rdev", "device type (if inode device)"},
552#endif
553 {0}
554};
555
556#ifdef HAVE_ST_BLKSIZE
557#define ST_BLKSIZE_IDX 10
558#else
559#define ST_BLKSIZE_IDX 9
560#endif
561
562#ifdef HAVE_ST_BLOCKS
563#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
564#else
565#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
566#endif
567
568#ifdef HAVE_ST_RDEV
569#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
570#else
571#define ST_RDEV_IDX ST_BLOCKS_IDX
572#endif
573
574static PyStructSequence_Desc stat_result_desc = {
575 "stat_result", /* name */
576 stat_result__doc__, /* doc */
577 stat_result_fields,
578 10
579};
580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000581PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000582"statvfs_result: Result from statvfs or fstatvfs.\n\n\
583This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000584 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
585or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000586\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000587See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000588
589static PyStructSequence_Field statvfs_result_fields[] = {
590 {"f_bsize", },
591 {"f_frsize", },
592 {"f_blocks", },
593 {"f_bfree", },
594 {"f_bavail", },
595 {"f_files", },
596 {"f_ffree", },
597 {"f_favail", },
598 {"f_flag", },
599 {"f_namemax",},
600 {0}
601};
602
603static PyStructSequence_Desc statvfs_result_desc = {
604 "statvfs_result", /* name */
605 statvfs_result__doc__, /* doc */
606 statvfs_result_fields,
607 10
608};
609
610static PyTypeObject StatResultType;
611static PyTypeObject StatVFSResultType;
612
Tim Peters5aa91602002-01-30 05:46:57 +0000613/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000614 (used by posix_stat() and posix_fstat()) */
615static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000616_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000617{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000618 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000619 if (v == NULL)
620 return NULL;
621
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000622 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000623#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000624 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000625 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000626#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000627 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000628#endif
629#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000630 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000631 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000632#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000633 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000634#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000635 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
636 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
637 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000638#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000639 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000640 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000641#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000642 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000643#endif
644#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000645 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000646 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000647 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000648 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000649 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000650 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000651#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000652 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
653 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
654 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
655#endif
656
657#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000658 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000659 PyInt_FromLong((long)st.st_blksize));
660#endif
661#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000662 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000663 PyInt_FromLong((long)st.st_blocks));
664#endif
665#ifdef HAVE_ST_RDEV
666 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
667 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000668#endif
669
670 if (PyErr_Occurred()) {
671 Py_DECREF(v);
672 return NULL;
673 }
674
675 return v;
676}
677
Barry Warsaw53699e91996-12-10 23:23:01 +0000678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000679posix_do_stat(PyObject *self, PyObject *args, char *format,
680 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681{
Fred Drake699f3522000-06-29 21:12:41 +0000682 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000683 char *path = NULL; /* pass this to stat; do not free() it */
684 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000685 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000686
687#ifdef MS_WIN32
Tim Peters500bd032001-12-19 19:05:01 +0000688 int pathlen;
689 char pathcopy[MAX_PATH];
Guido van Rossumace88ae2000-04-21 18:54:45 +0000690#endif /* MS_WIN32 */
691
Tim Peters5aa91602002-01-30 05:46:57 +0000692 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000693 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000695 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000696
697#ifdef MS_WIN32
698 pathlen = strlen(path);
699 /* the library call can blow up if the file name is too long! */
700 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000701 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000702 errno = ENAMETOOLONG;
703 return posix_error();
704 }
705
Tim Peters500bd032001-12-19 19:05:01 +0000706 /* Remove trailing slash or backslash, unless it's the current
707 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
708 */
709 if (pathlen > 0 &&
710 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
711 /* It does end with a slash -- exempt the root drive cases. */
712 /* XXX UNC root drives should also be exempted? */
713 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
714 /* leave it alone */;
715 else {
716 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000717 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000718 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000719 path = pathcopy;
720 }
721 }
722#endif /* MS_WIN32 */
723
Barry Warsaw53699e91996-12-10 23:23:01 +0000724 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000725 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000726 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000727 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000728 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000729
Tim Peters500bd032001-12-19 19:05:01 +0000730 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000731 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000732}
733
734
735/* POSIX methods */
736
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000737PyDoc_STRVAR(posix_access__doc__,
Guido van Rossum015f22a1999-01-06 22:52:38 +0000738"access(path, mode) -> 1 if granted, 0 otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000739Test for access to a file.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000740
741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000742posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000743{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000744 char *path;
745 int mode;
746 int res;
747
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000748 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000749 return NULL;
750 Py_BEGIN_ALLOW_THREADS
751 res = access(path, mode);
752 Py_END_ALLOW_THREADS
753 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000754}
755
Guido van Rossumd371ff11999-01-25 16:12:23 +0000756#ifndef F_OK
757#define F_OK 0
758#endif
759#ifndef R_OK
760#define R_OK 4
761#endif
762#ifndef W_OK
763#define W_OK 2
764#endif
765#ifndef X_OK
766#define X_OK 1
767#endif
768
769#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000770PyDoc_STRVAR(posix_ttyname__doc__,
Guido van Rossum61eeb041999-02-22 15:29:15 +0000771"ttyname(fd) -> String\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000772Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000773
774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000775posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000776{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000777 int id;
778 char *ret;
779
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000780 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000781 return NULL;
782
Guido van Rossum94f6f721999-01-06 18:42:14 +0000783 ret = ttyname(id);
784 if (ret == NULL)
785 return(posix_error());
786 return(PyString_FromString(ret));
787}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000788#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000789
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000790#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000791PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000792"ctermid() -> String\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000793Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000794
795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000796posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000797{
798 char *ret;
799 char buffer[L_ctermid];
800
801 if (!PyArg_ParseTuple(args, ":ctermid"))
802 return NULL;
803
Greg Wardb48bc172000-03-01 21:51:56 +0000804#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000805 ret = ctermid_r(buffer);
806#else
807 ret = ctermid(buffer);
808#endif
809 if (ret == NULL)
810 return(posix_error());
811 return(PyString_FromString(buffer));
812}
813#endif
814
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000815PyDoc_STRVAR(posix_chdir__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000816"chdir(path) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000817Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000818
Barry Warsaw53699e91996-12-10 23:23:01 +0000819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000820posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000821{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000822#if defined(PYOS_OS2) && defined(PYCC_GCC)
823 return posix_1str(args, "et:chdir", _chdir2);
824#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000825 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000826#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000827}
828
Fred Drake4d1e64b2002-04-15 19:40:07 +0000829#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000830PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drake4d1e64b2002-04-15 19:40:07 +0000831"fchdir(fildes) -> None\n\
832Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000833opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +0000834
835static PyObject *
836posix_fchdir(PyObject *self, PyObject *fdobj)
837{
838 return posix_fildes(fdobj, fchdir);
839}
840#endif /* HAVE_FCHDIR */
841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000842
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000843PyDoc_STRVAR(posix_chmod__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000844"chmod(path, mode) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000845Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000846
Barry Warsaw53699e91996-12-10 23:23:01 +0000847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000848posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000849{
Mark Hammondef8b6542001-05-13 08:04:26 +0000850 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000851 int i;
852 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000853 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000854 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000855 return NULL;
856 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000857 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000858 Py_END_ALLOW_THREADS
859 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000860 return posix_error_with_allocated_filename(path);
861 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000862 Py_INCREF(Py_None);
863 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000864}
865
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000866
Martin v. Löwis244edc82001-10-04 22:44:26 +0000867#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000868PyDoc_STRVAR(posix_chroot__doc__,
Martin v. Löwis244edc82001-10-04 22:44:26 +0000869"chroot(path) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000870Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +0000871
872static PyObject *
873posix_chroot(PyObject *self, PyObject *args)
874{
875 return posix_1str(args, "et:chroot", chroot);
876}
877#endif
878
Guido van Rossum21142a01999-01-08 21:05:37 +0000879#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000880PyDoc_STRVAR(posix_fsync__doc__,
Guido van Rossum21142a01999-01-08 21:05:37 +0000881"fsync(fildes) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000882force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000883
884static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000885posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000886{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000887 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000888}
889#endif /* HAVE_FSYNC */
890
891#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000892
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000893#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000894extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
895#endif
896
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000897PyDoc_STRVAR(posix_fdatasync__doc__,
Guido van Rossum21142a01999-01-08 21:05:37 +0000898"fdatasync(fildes) -> None\n\
899force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000900 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000901
902static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000903posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000904{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000905 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000906}
907#endif /* HAVE_FDATASYNC */
908
909
Fredrik Lundh10723342000-07-10 16:38:09 +0000910#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000911PyDoc_STRVAR(posix_chown__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000912"chown(path, uid, gid) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000913Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000914
Barry Warsaw53699e91996-12-10 23:23:01 +0000915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000916posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000917{
Mark Hammondef8b6542001-05-13 08:04:26 +0000918 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000919 int uid, gid;
920 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000921 if (!PyArg_ParseTuple(args, "etii:chown",
922 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000923 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000924 return NULL;
925 Py_BEGIN_ALLOW_THREADS
926 res = chown(path, (uid_t) uid, (gid_t) gid);
927 Py_END_ALLOW_THREADS
928 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000929 return posix_error_with_allocated_filename(path);
930 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000931 Py_INCREF(Py_None);
932 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000933}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000934#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000935
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000936
Guido van Rossum36bc6801995-06-14 22:54:23 +0000937#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000938PyDoc_STRVAR(posix_getcwd__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000939"getcwd() -> path\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000940Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000941
Barry Warsaw53699e91996-12-10 23:23:01 +0000942static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000943posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000944{
945 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000946 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000947 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000948 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000949 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000950#if defined(PYOS_OS2) && defined(PYCC_GCC)
951 res = _getcwd2(buf, sizeof buf);
952#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000953 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000954#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000955 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000956 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000957 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000958 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000959}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000960#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000961
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000962
Guido van Rossumb6775db1994-08-01 11:34:53 +0000963#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000964PyDoc_STRVAR(posix_link__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000965"link(src, dst) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000966Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000967
Barry Warsaw53699e91996-12-10 23:23:01 +0000968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000969posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000970{
Mark Hammondef8b6542001-05-13 08:04:26 +0000971 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000972}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000973#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000975
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000976PyDoc_STRVAR(posix_listdir__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000977"listdir(path) -> list_of_strings\n\
978Return a list containing the names of the entries in the directory.\n\
979\n\
980 path: path of directory to list\n\
981\n\
982The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000983entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000984
Barry Warsaw53699e91996-12-10 23:23:01 +0000985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000986posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000987{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000988 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000989 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000990#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000991
Barry Warsaw53699e91996-12-10 23:23:01 +0000992 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000993 HANDLE hFindFile;
994 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000995 /* MAX_PATH characters could mean a bigger encoded string */
996 char namebuf[MAX_PATH*2+5];
997 char *bufptr = namebuf;
998 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000999
Tim Peters5aa91602002-01-30 05:46:57 +00001000 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001001 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001002 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001003 if (len > 0) {
1004 char ch = namebuf[len-1];
1005 if (ch != SEP && ch != ALTSEP && ch != ':')
1006 namebuf[len++] = '/';
1007 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001008 strcpy(namebuf + len, "*.*");
1009
Barry Warsaw53699e91996-12-10 23:23:01 +00001010 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001011 return NULL;
1012
1013 hFindFile = FindFirstFile(namebuf, &FileData);
1014 if (hFindFile == INVALID_HANDLE_VALUE) {
1015 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001016 if (errno == ERROR_FILE_NOT_FOUND)
1017 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001018 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001019 }
1020 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001021 if (FileData.cFileName[0] == '.' &&
1022 (FileData.cFileName[1] == '\0' ||
1023 FileData.cFileName[1] == '.' &&
1024 FileData.cFileName[2] == '\0'))
1025 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001026 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001027 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001028 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001029 d = NULL;
1030 break;
1031 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001032 if (PyList_Append(d, v) != 0) {
1033 Py_DECREF(v);
1034 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001035 d = NULL;
1036 break;
1037 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001038 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001039 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1040
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001041 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001042 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001043
1044 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001045
Tim Peters0bb44a42000-09-15 07:44:49 +00001046#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001047
1048#ifndef MAX_PATH
1049#define MAX_PATH 250
1050#endif
1051 char *name, *pt;
1052 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001053 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001054 char namebuf[MAX_PATH+5];
1055 struct _find_t ep;
1056
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001057 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001058 return NULL;
1059 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001060 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001061 return NULL;
1062 }
1063 strcpy(namebuf, name);
1064 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001065 if (*pt == ALTSEP)
1066 *pt = SEP;
1067 if (namebuf[len-1] != SEP)
1068 namebuf[len++] = SEP;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001069 strcpy(namebuf + len, "*.*");
1070
Barry Warsaw53699e91996-12-10 23:23:01 +00001071 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001072 return NULL;
1073
1074 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001075 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1076 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001077 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001078 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001079 }
1080 do {
1081 if (ep.name[0] == '.' &&
1082 (ep.name[1] == '\0' ||
1083 ep.name[1] == '.' &&
1084 ep.name[2] == '\0'))
1085 continue;
1086 strcpy(namebuf, ep.name);
1087 for (pt = namebuf; *pt; pt++)
1088 if (isupper(*pt))
1089 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001090 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001091 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001092 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001093 d = NULL;
1094 break;
1095 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001096 if (PyList_Append(d, v) != 0) {
1097 Py_DECREF(v);
1098 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001099 d = NULL;
1100 break;
1101 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001102 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001103 } while (_dos_findnext(&ep) == 0);
1104
1105 return d;
1106
Tim Peters0bb44a42000-09-15 07:44:49 +00001107#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001108
1109#ifndef MAX_PATH
1110#define MAX_PATH CCHMAXPATH
1111#endif
1112 char *name, *pt;
1113 int len;
1114 PyObject *d, *v;
1115 char namebuf[MAX_PATH+5];
1116 HDIR hdir = 1;
1117 ULONG srchcnt = 1;
1118 FILEFINDBUF3 ep;
1119 APIRET rc;
1120
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001121 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001122 return NULL;
1123 if (len >= MAX_PATH) {
1124 PyErr_SetString(PyExc_ValueError, "path too long");
1125 return NULL;
1126 }
1127 strcpy(namebuf, name);
1128 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001129 if (*pt == ALTSEP)
1130 *pt = SEP;
1131 if (namebuf[len-1] != SEP)
1132 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001133 strcpy(namebuf + len, "*.*");
1134
1135 if ((d = PyList_New(0)) == NULL)
1136 return NULL;
1137
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001138 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1139 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001140 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001141 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1142 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1143 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001144
1145 if (rc != NO_ERROR) {
1146 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001147 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001148 }
1149
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001150 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001151 do {
1152 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001153 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001154 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001155
1156 strcpy(namebuf, ep.achName);
1157
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001158 /* Leave Case of Name Alone -- In Native Form */
1159 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001160
1161 v = PyString_FromString(namebuf);
1162 if (v == NULL) {
1163 Py_DECREF(d);
1164 d = NULL;
1165 break;
1166 }
1167 if (PyList_Append(d, v) != 0) {
1168 Py_DECREF(v);
1169 Py_DECREF(d);
1170 d = NULL;
1171 break;
1172 }
1173 Py_DECREF(v);
1174 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1175 }
1176
1177 return d;
1178#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001179
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001180 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001181 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001183 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001184 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001186 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001187 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001188 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001189 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001190 closedir(dirp);
1191 return NULL;
1192 }
1193 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001194 if (ep->d_name[0] == '.' &&
1195 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001196 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001197 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001198 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001199 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001200 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001201 d = NULL;
1202 break;
1203 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001204 if (PyList_Append(d, v) != 0) {
1205 Py_DECREF(v);
1206 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001207 d = NULL;
1208 break;
1209 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001210 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211 }
1212 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001213
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001215
Tim Peters0bb44a42000-09-15 07:44:49 +00001216#endif /* which OS */
1217} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218
Mark Hammondef8b6542001-05-13 08:04:26 +00001219#ifdef MS_WIN32
1220/* A helper function for abspath on win32 */
1221static PyObject *
1222posix__getfullpathname(PyObject *self, PyObject *args)
1223{
1224 /* assume encoded strings wont more than double no of chars */
1225 char inbuf[MAX_PATH*2];
1226 char *inbufp = inbuf;
1227 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1228 char outbuf[MAX_PATH*2];
1229 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001230 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1231 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001232 &insize))
1233 return NULL;
1234 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1235 outbuf, &temp))
1236 return win32_error("GetFullPathName", inbuf);
1237 return PyString_FromString(outbuf);
1238} /* end of posix__getfullpathname */
1239#endif /* MS_WIN32 */
1240
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001241PyDoc_STRVAR(posix_mkdir__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001242"mkdir(path [, mode=0777]) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001243Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001244
Barry Warsaw53699e91996-12-10 23:23:01 +00001245static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001246posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001247{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001248 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001249 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001250 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001251 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001252 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001253 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001254 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001255#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001256 res = mkdir(path);
1257#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001258 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001259#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001260 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001261 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001262 return posix_error_with_allocated_filename(path);
1263 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001264 Py_INCREF(Py_None);
1265 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001266}
1267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001268
Guido van Rossumb6775db1994-08-01 11:34:53 +00001269#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001270#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1271#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1272#include <sys/resource.h>
1273#endif
1274#endif
1275
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001276PyDoc_STRVAR(posix_nice__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001277"nice(inc) -> new_priority\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001278Decrease the priority of process and return new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001279
Barry Warsaw53699e91996-12-10 23:23:01 +00001280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001281posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001282{
1283 int increment, value;
1284
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001285 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001286 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001287
1288 /* There are two flavours of 'nice': one that returns the new
1289 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001290 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1291 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001292
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001293 If we are of the nice family that returns the new priority, we
1294 need to clear errno before the call, and check if errno is filled
1295 before calling posix_error() on a returnvalue of -1, because the
1296 -1 may be the actual new priority! */
1297
1298 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001299 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001300#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001301 if (value == 0)
1302 value = getpriority(PRIO_PROCESS, 0);
1303#endif
1304 if (value == -1 && errno != 0)
1305 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001306 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001307 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001308}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001309#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001311
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001312PyDoc_STRVAR(posix_rename__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001313"rename(old, new) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001314Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001315
Barry Warsaw53699e91996-12-10 23:23:01 +00001316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001317posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001318{
Mark Hammondef8b6542001-05-13 08:04:26 +00001319 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001320}
1321
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001322
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001323PyDoc_STRVAR(posix_rmdir__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001324"rmdir(path) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001325Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001326
Barry Warsaw53699e91996-12-10 23:23:01 +00001327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001328posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001329{
Mark Hammondef8b6542001-05-13 08:04:26 +00001330 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331}
1332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001333
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001334PyDoc_STRVAR(posix_stat__doc__,
Fred Drake193a3f62002-03-12 21:38:49 +00001335"stat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
1336 st_size, st_atime, st_mtime, st_ctime)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001337Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001338
Barry Warsaw53699e91996-12-10 23:23:01 +00001339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001340posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341{
Mark Hammondef8b6542001-05-13 08:04:26 +00001342 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001343}
1344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001345
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001346#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001347PyDoc_STRVAR(posix_system__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001348"system(command) -> exit_status\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001349Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001350
Barry Warsaw53699e91996-12-10 23:23:01 +00001351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001352posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001353{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001354 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001355 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001356 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001358 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001359 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001360 Py_END_ALLOW_THREADS
1361 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001363#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001365
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001366PyDoc_STRVAR(posix_umask__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001367"umask(new_mask) -> old_mask\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001368Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001369
Barry Warsaw53699e91996-12-10 23:23:01 +00001370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001371posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001372{
1373 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001374 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001375 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001376 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001377 if (i < 0)
1378 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001379 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001380}
1381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001383PyDoc_STRVAR(posix_unlink__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001384"unlink(path) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001385Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001386
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001387PyDoc_STRVAR(posix_remove__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001388"remove(path) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001389Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001390
Barry Warsaw53699e91996-12-10 23:23:01 +00001391static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001392posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393{
Mark Hammondef8b6542001-05-13 08:04:26 +00001394 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001395}
1396
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001397
Guido van Rossumb6775db1994-08-01 11:34:53 +00001398#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001399PyDoc_STRVAR(posix_uname__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001400"uname() -> (sysname, nodename, release, version, machine)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001401Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001402
Barry Warsaw53699e91996-12-10 23:23:01 +00001403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001404posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001405{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001406 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001407 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001408 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001409 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001410 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001411 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001412 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001413 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001414 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001415 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001416 u.sysname,
1417 u.nodename,
1418 u.release,
1419 u.version,
1420 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001421}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001422#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001423
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001424
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001425PyDoc_STRVAR(posix_utime__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001426"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001427utime(path, None) -> None\n\
1428Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001429second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001430
Barry Warsaw53699e91996-12-10 23:23:01 +00001431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001432posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001433{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001434 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001435 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001436 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001437 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001438
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001439/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001440#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001441 struct utimbuf buf;
1442#define ATIME buf.actime
1443#define MTIME buf.modtime
1444#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001445#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001446 time_t buf[2];
1447#define ATIME buf[0]
1448#define MTIME buf[1]
1449#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001450#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001451
Barry Warsaw3cef8562000-05-01 16:17:24 +00001452 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001453 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001454 if (arg == Py_None) {
1455 /* optional time values not given */
1456 Py_BEGIN_ALLOW_THREADS
1457 res = utime(path, NULL);
1458 Py_END_ALLOW_THREADS
1459 }
1460 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1461 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001462 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001463 return NULL;
1464 }
1465 else {
1466 ATIME = atime;
1467 MTIME = mtime;
1468 Py_BEGIN_ALLOW_THREADS
1469 res = utime(path, UTIME_ARG);
1470 Py_END_ALLOW_THREADS
1471 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001472 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001473 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001474 Py_INCREF(Py_None);
1475 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001476#undef UTIME_ARG
1477#undef ATIME
1478#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001479}
1480
Guido van Rossum85e3b011991-06-03 12:42:10 +00001481
Guido van Rossum3b066191991-06-04 19:40:25 +00001482/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001483
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001484PyDoc_STRVAR(posix__exit__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001485"_exit(status)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001486Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001487
Barry Warsaw53699e91996-12-10 23:23:01 +00001488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001489posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001490{
1491 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001492 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001493 return NULL;
1494 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001495 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001496}
1497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001498
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001499#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001500PyDoc_STRVAR(posix_execv__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001501"execv(path, args)\n\
1502Execute an executable path with arguments, replacing current process.\n\
1503\n\
1504 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001505 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001506
Barry Warsaw53699e91996-12-10 23:23:01 +00001507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001508posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001509{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001510 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001511 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001512 char **argvlist;
1513 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001514 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001515
Guido van Rossum89b33251993-10-22 14:26:06 +00001516 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001517 argv is a list or tuple of strings. */
1518
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001519 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001520 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001521 if (PyList_Check(argv)) {
1522 argc = PyList_Size(argv);
1523 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001524 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001525 else if (PyTuple_Check(argv)) {
1526 argc = PyTuple_Size(argv);
1527 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001528 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001529 else {
Fred Drake661ea262000-10-24 19:57:45 +00001530 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001531 return NULL;
1532 }
1533
1534 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001535 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001536 return NULL;
1537 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001538
Barry Warsaw53699e91996-12-10 23:23:01 +00001539 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001540 if (argvlist == NULL)
1541 return NULL;
1542 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001543 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1544 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001545 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001546 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001547 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001548
Guido van Rossum85e3b011991-06-03 12:42:10 +00001549 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001550 }
1551 argvlist[argc] = NULL;
1552
Guido van Rossumb6775db1994-08-01 11:34:53 +00001553#ifdef BAD_EXEC_PROTOTYPES
1554 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001555#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001556 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001557#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001558
Guido van Rossum85e3b011991-06-03 12:42:10 +00001559 /* If we get here it's definitely an error */
1560
Barry Warsaw53699e91996-12-10 23:23:01 +00001561 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001562 return posix_error();
1563}
1564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001565
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001566PyDoc_STRVAR(posix_execve__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001567"execve(path, args, env)\n\
1568Execute a path with arguments and environment, replacing current process.\n\
1569\n\
1570 path: path of executable file\n\
1571 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001572 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001573
Barry Warsaw53699e91996-12-10 23:23:01 +00001574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001575posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001576{
1577 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001578 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001579 char **argvlist;
1580 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001581 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001582 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001583 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001584
1585 /* execve has three arguments: (path, argv, env), where
1586 argv is a list or tuple of strings and env is a dictionary
1587 like posix.environ. */
1588
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001589 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001590 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001591 if (PyList_Check(argv)) {
1592 argc = PyList_Size(argv);
1593 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001594 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001595 else if (PyTuple_Check(argv)) {
1596 argc = PyTuple_Size(argv);
1597 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001598 }
1599 else {
Fred Drake661ea262000-10-24 19:57:45 +00001600 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 return NULL;
1602 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001603 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001604 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001605 return NULL;
1606 }
1607
Guido van Rossum50422b42000-04-26 20:34:28 +00001608 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001609 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001610 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001611 return NULL;
1612 }
1613
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001615 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001616 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001617 return NULL;
1618 }
1619 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001620 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001621 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001622 &argvlist[i]))
1623 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001624 goto fail_1;
1625 }
1626 }
1627 argvlist[argc] = NULL;
1628
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001629 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001630 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001631 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001632 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001633 goto fail_1;
1634 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001635 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001636 keys = PyMapping_Keys(env);
1637 vals = PyMapping_Values(env);
1638 if (!keys || !vals)
1639 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001640
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001641 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001642 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001643 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001644
1645 key = PyList_GetItem(keys, pos);
1646 val = PyList_GetItem(vals, pos);
1647 if (!key || !val)
1648 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001649
Fred Drake661ea262000-10-24 19:57:45 +00001650 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1651 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001652 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001653 goto fail_2;
1654 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001655
1656#if defined(PYOS_OS2)
1657 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1658 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1659#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001660 len = PyString_Size(key) + PyString_Size(val) + 2;
1661 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001662 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001663 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001664 goto fail_2;
1665 }
Tim Petersc8996f52001-12-03 20:41:00 +00001666 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001667 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001668#if defined(PYOS_OS2)
1669 }
1670#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001671 }
1672 envlist[envc] = 0;
1673
Guido van Rossumb6775db1994-08-01 11:34:53 +00001674
1675#ifdef BAD_EXEC_PROTOTYPES
1676 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001677#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001678 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001679#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001680
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001681 /* If we get here it's definitely an error */
1682
1683 (void) posix_error();
1684
1685 fail_2:
1686 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001687 PyMem_DEL(envlist[envc]);
1688 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001689 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001690 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001691 Py_XDECREF(vals);
1692 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001693 return NULL;
1694}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001695#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001696
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001697
Guido van Rossuma1065681999-01-25 23:20:23 +00001698#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001699PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakea6dff3e1999-02-01 22:24:40 +00001700"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001701Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001702\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001703 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001704 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001705 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001706
1707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001708posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001709{
1710 char *path;
1711 PyObject *argv;
1712 char **argvlist;
1713 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001714 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001715 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001716
1717 /* spawnv has three arguments: (mode, path, argv), where
1718 argv is a list or tuple of strings. */
1719
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001720 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001721 return NULL;
1722 if (PyList_Check(argv)) {
1723 argc = PyList_Size(argv);
1724 getitem = PyList_GetItem;
1725 }
1726 else if (PyTuple_Check(argv)) {
1727 argc = PyTuple_Size(argv);
1728 getitem = PyTuple_GetItem;
1729 }
1730 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001731 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001732 return NULL;
1733 }
1734
1735 argvlist = PyMem_NEW(char *, argc+1);
1736 if (argvlist == NULL)
1737 return NULL;
1738 for (i = 0; i < argc; i++) {
1739 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1740 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001741 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001742 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001743 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001744 }
1745 }
1746 argvlist[argc] = NULL;
1747
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001748#if defined(PYOS_OS2) && defined(PYCC_GCC)
1749 Py_BEGIN_ALLOW_THREADS
1750 spawnval = spawnv(mode, path, argvlist);
1751 Py_END_ALLOW_THREADS
1752#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001753 if (mode == _OLD_P_OVERLAY)
1754 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001755
Tim Peters25059d32001-12-07 20:35:43 +00001756 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001757 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001758 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001759#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001760
Guido van Rossuma1065681999-01-25 23:20:23 +00001761 PyMem_DEL(argvlist);
1762
Fred Drake699f3522000-06-29 21:12:41 +00001763 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001764 return posix_error();
1765 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001766#if SIZEOF_LONG == SIZEOF_VOID_P
1767 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001768#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001769 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001770#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001771}
1772
1773
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001774PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakea6dff3e1999-02-01 22:24:40 +00001775"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001776Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001777\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001778 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001779 path: path of executable file\n\
1780 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001781 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001782
1783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001784posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001785{
1786 char *path;
1787 PyObject *argv, *env;
1788 char **argvlist;
1789 char **envlist;
1790 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1791 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001792 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001793 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001794
1795 /* spawnve has four arguments: (mode, path, argv, env), where
1796 argv is a list or tuple of strings and env is a dictionary
1797 like posix.environ. */
1798
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001799 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001800 return NULL;
1801 if (PyList_Check(argv)) {
1802 argc = PyList_Size(argv);
1803 getitem = PyList_GetItem;
1804 }
1805 else if (PyTuple_Check(argv)) {
1806 argc = PyTuple_Size(argv);
1807 getitem = PyTuple_GetItem;
1808 }
1809 else {
Fred Drake661ea262000-10-24 19:57:45 +00001810 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001811 return NULL;
1812 }
1813 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001814 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001815 return NULL;
1816 }
1817
1818 argvlist = PyMem_NEW(char *, argc+1);
1819 if (argvlist == NULL) {
1820 PyErr_NoMemory();
1821 return NULL;
1822 }
1823 for (i = 0; i < argc; i++) {
1824 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001825 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001826 &argvlist[i]))
1827 {
1828 goto fail_1;
1829 }
1830 }
1831 argvlist[argc] = NULL;
1832
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001833 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001834 envlist = PyMem_NEW(char *, i + 1);
1835 if (envlist == NULL) {
1836 PyErr_NoMemory();
1837 goto fail_1;
1838 }
1839 envc = 0;
1840 keys = PyMapping_Keys(env);
1841 vals = PyMapping_Values(env);
1842 if (!keys || !vals)
1843 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001844
Guido van Rossuma1065681999-01-25 23:20:23 +00001845 for (pos = 0; pos < i; pos++) {
1846 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001847 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001848
1849 key = PyList_GetItem(keys, pos);
1850 val = PyList_GetItem(vals, pos);
1851 if (!key || !val)
1852 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001853
Fred Drake661ea262000-10-24 19:57:45 +00001854 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1855 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001856 {
1857 goto fail_2;
1858 }
Tim Petersc8996f52001-12-03 20:41:00 +00001859 len = PyString_Size(key) + PyString_Size(val) + 2;
1860 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001861 if (p == NULL) {
1862 PyErr_NoMemory();
1863 goto fail_2;
1864 }
Tim Petersc8996f52001-12-03 20:41:00 +00001865 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001866 envlist[envc++] = p;
1867 }
1868 envlist[envc] = 0;
1869
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001870#if defined(PYOS_OS2) && defined(PYCC_GCC)
1871 Py_BEGIN_ALLOW_THREADS
1872 spawnval = spawnve(mode, path, argvlist, envlist);
1873 Py_END_ALLOW_THREADS
1874#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001875 if (mode == _OLD_P_OVERLAY)
1876 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001877
1878 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001879 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001880 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001881#endif
Tim Peters25059d32001-12-07 20:35:43 +00001882
Fred Drake699f3522000-06-29 21:12:41 +00001883 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001884 (void) posix_error();
1885 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001886#if SIZEOF_LONG == SIZEOF_VOID_P
1887 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001888#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001889 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001890#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001891
1892 fail_2:
1893 while (--envc >= 0)
1894 PyMem_DEL(envlist[envc]);
1895 PyMem_DEL(envlist);
1896 fail_1:
1897 PyMem_DEL(argvlist);
1898 Py_XDECREF(vals);
1899 Py_XDECREF(keys);
1900 return res;
1901}
1902#endif /* HAVE_SPAWNV */
1903
1904
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001905#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001906PyDoc_STRVAR(posix_fork1__doc__,
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001907"fork1() -> pid\n\
1908Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1909\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001910Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001911
1912static PyObject *
1913posix_fork1(self, args)
1914 PyObject *self;
1915 PyObject *args;
1916{
1917 int pid;
1918 if (!PyArg_ParseTuple(args, ":fork1"))
1919 return NULL;
1920 pid = fork1();
1921 if (pid == -1)
1922 return posix_error();
1923 PyOS_AfterFork();
1924 return PyInt_FromLong((long)pid);
1925}
1926#endif
1927
1928
Guido van Rossumad0ee831995-03-01 10:34:45 +00001929#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001930PyDoc_STRVAR(posix_fork__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001931"fork() -> pid\n\
1932Fork a child process.\n\
1933\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001934Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001935
Barry Warsaw53699e91996-12-10 23:23:01 +00001936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001937posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001938{
1939 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001940 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001941 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001942 pid = fork();
1943 if (pid == -1)
1944 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001945 if (pid == 0)
1946 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001947 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001948}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001949#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001950
Fred Drake8cef4cf2000-06-28 16:40:38 +00001951#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1952#ifdef HAVE_PTY_H
1953#include <pty.h>
1954#else
1955#ifdef HAVE_LIBUTIL_H
1956#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001957#endif /* HAVE_LIBUTIL_H */
1958#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001959#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001960
Thomas Wouters70c21a12000-07-14 14:28:33 +00001961#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001962PyDoc_STRVAR(posix_openpty__doc__,
Fred Drake8cef4cf2000-06-28 16:40:38 +00001963"openpty() -> (master_fd, slave_fd)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001964Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001965
1966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001967posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001968{
1969 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001970#ifndef HAVE_OPENPTY
1971 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001972#endif
1973
Fred Drake8cef4cf2000-06-28 16:40:38 +00001974 if (!PyArg_ParseTuple(args, ":openpty"))
1975 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001976
1977#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001978 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1979 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001980#else
1981 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1982 if (slave_name == NULL)
1983 return posix_error();
1984
1985 slave_fd = open(slave_name, O_RDWR);
1986 if (slave_fd < 0)
1987 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001988#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001989
Fred Drake8cef4cf2000-06-28 16:40:38 +00001990 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001991
Fred Drake8cef4cf2000-06-28 16:40:38 +00001992}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001993#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001994
1995#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001996PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drake8cef4cf2000-06-28 16:40:38 +00001997"forkpty() -> (pid, master_fd)\n\
1998Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1999Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002000To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002001
2002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002003posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002004{
2005 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002006
Fred Drake8cef4cf2000-06-28 16:40:38 +00002007 if (!PyArg_ParseTuple(args, ":forkpty"))
2008 return NULL;
2009 pid = forkpty(&master_fd, NULL, NULL, NULL);
2010 if (pid == -1)
2011 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002012 if (pid == 0)
2013 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002014 return Py_BuildValue("(ii)", pid, master_fd);
2015}
2016#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002017
Guido van Rossumad0ee831995-03-01 10:34:45 +00002018#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002019PyDoc_STRVAR(posix_getegid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002020"getegid() -> egid\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002021Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002022
Barry Warsaw53699e91996-12-10 23:23:01 +00002023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002024posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002025{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002026 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002027 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002028 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002029}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002030#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002032
Guido van Rossumad0ee831995-03-01 10:34:45 +00002033#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034PyDoc_STRVAR(posix_geteuid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002035"geteuid() -> euid\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002036Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002037
Barry Warsaw53699e91996-12-10 23:23:01 +00002038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002039posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002040{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002041 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002042 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002043 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002044}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002045#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002046
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002047
Guido van Rossumad0ee831995-03-01 10:34:45 +00002048#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002049PyDoc_STRVAR(posix_getgid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002050"getgid() -> gid\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002051Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002052
Barry Warsaw53699e91996-12-10 23:23:01 +00002053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002054posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002055{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002056 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002057 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002058 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002059}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002060#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002062
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002063PyDoc_STRVAR(posix_getpid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002064"getpid() -> pid\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002065Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002066
Barry Warsaw53699e91996-12-10 23:23:01 +00002067static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002068posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002069{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002070 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002071 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002072 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002073}
2074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
Fred Drakec9680921999-12-13 16:37:25 +00002076#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077PyDoc_STRVAR(posix_getgroups__doc__,
2078"getgroups() -> list of group IDs\n\
2079Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002080
2081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002082posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002083{
2084 PyObject *result = NULL;
2085
2086 if (PyArg_ParseTuple(args, ":getgroups")) {
2087#ifdef NGROUPS_MAX
2088#define MAX_GROUPS NGROUPS_MAX
2089#else
2090 /* defined to be 16 on Solaris7, so this should be a small number */
2091#define MAX_GROUPS 64
2092#endif
2093 gid_t grouplist[MAX_GROUPS];
2094 int n;
2095
2096 n = getgroups(MAX_GROUPS, grouplist);
2097 if (n < 0)
2098 posix_error();
2099 else {
2100 result = PyList_New(n);
2101 if (result != NULL) {
2102 PyObject *o;
2103 int i;
2104 for (i = 0; i < n; ++i) {
2105 o = PyInt_FromLong((long)grouplist[i]);
2106 if (o == NULL) {
2107 Py_DECREF(result);
2108 result = NULL;
2109 break;
2110 }
2111 PyList_SET_ITEM(result, i, o);
2112 }
2113 }
2114 }
2115 }
2116 return result;
2117}
2118#endif
2119
Martin v. Löwis606edc12002-06-13 21:09:11 +00002120#ifdef HAVE_GETPGID
2121static char posix_getpgid__doc__[] =
2122"getpgid(pid) -> pgid\n\
2123Call the system call getpgid().";
2124
2125static PyObject *
2126posix_getpgid(PyObject *self, PyObject *args)
2127{
2128 int pid, pgid;
2129 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2130 return NULL;
2131 pgid = getpgid(pid);
2132 if (pgid < 0)
2133 return posix_error();
2134 return PyInt_FromLong((long)pgid);
2135}
2136#endif /* HAVE_GETPGID */
2137
2138
Guido van Rossumb6775db1994-08-01 11:34:53 +00002139#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002140PyDoc_STRVAR(posix_getpgrp__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002141"getpgrp() -> pgrp\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002143
Barry Warsaw53699e91996-12-10 23:23:01 +00002144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002145posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002146{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002147 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002148 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002149#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002150 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002151#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002152 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002153#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002154}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002155#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002156
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002157
Guido van Rossumb6775db1994-08-01 11:34:53 +00002158#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002159PyDoc_STRVAR(posix_setpgrp__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002160"setpgrp() -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002161Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002162
Barry Warsaw53699e91996-12-10 23:23:01 +00002163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002164posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002165{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002166 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002167 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002168#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002169 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002170#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002171 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002172#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002173 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002174 Py_INCREF(Py_None);
2175 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002176}
2177
Guido van Rossumb6775db1994-08-01 11:34:53 +00002178#endif /* HAVE_SETPGRP */
2179
Guido van Rossumad0ee831995-03-01 10:34:45 +00002180#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002181PyDoc_STRVAR(posix_getppid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002182"getppid() -> ppid\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002183Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002184
Barry Warsaw53699e91996-12-10 23:23:01 +00002185static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002186posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002187{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002188 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002189 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002190 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002191}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002192#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002194
Fred Drake12c6e2d1999-12-14 21:25:03 +00002195#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002196PyDoc_STRVAR(posix_getlogin__doc__,
2197"getlogin() -> string\n\
2198Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002199
2200static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002201posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002202{
2203 PyObject *result = NULL;
2204
2205 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002206 char *name;
2207 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002208
Fred Drakea30680b2000-12-06 21:24:28 +00002209 errno = 0;
2210 name = getlogin();
2211 if (name == NULL) {
2212 if (errno)
2213 posix_error();
2214 else
2215 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002216 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002217 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002218 else
2219 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002220 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002221 }
2222 return result;
2223}
2224#endif
2225
Guido van Rossumad0ee831995-03-01 10:34:45 +00002226#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002227PyDoc_STRVAR(posix_getuid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002228"getuid() -> uid\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002229Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002230
Barry Warsaw53699e91996-12-10 23:23:01 +00002231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002232posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002233{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002234 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002235 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002236 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002237}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002238#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002239
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002240
Guido van Rossumad0ee831995-03-01 10:34:45 +00002241#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002242PyDoc_STRVAR(posix_kill__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002243"kill(pid, sig) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002244Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002245
Barry Warsaw53699e91996-12-10 23:23:01 +00002246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002247posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002248{
2249 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002250 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002251 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002252#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002253 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2254 APIRET rc;
2255 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002256 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002257
2258 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2259 APIRET rc;
2260 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002261 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002262
2263 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002264 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002265#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002266 if (kill(pid, sig) == -1)
2267 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002268#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002269 Py_INCREF(Py_None);
2270 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002271}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002272#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002273
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002274#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002275PyDoc_STRVAR(posix_killpg__doc__,
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002276"killpg(pgid, sig) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002277Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002278
2279static PyObject *
2280posix_killpg(PyObject *self, PyObject *args)
2281{
2282 int pgid, sig;
2283 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2284 return NULL;
2285 if (killpg(pgid, sig) == -1)
2286 return posix_error();
2287 Py_INCREF(Py_None);
2288 return Py_None;
2289}
2290#endif
2291
Guido van Rossumc0125471996-06-28 18:55:32 +00002292#ifdef HAVE_PLOCK
2293
2294#ifdef HAVE_SYS_LOCK_H
2295#include <sys/lock.h>
2296#endif
2297
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002298PyDoc_STRVAR(posix_plock__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002299"plock(op) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002300Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002301
Barry Warsaw53699e91996-12-10 23:23:01 +00002302static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002303posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002304{
2305 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002306 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002307 return NULL;
2308 if (plock(op) == -1)
2309 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002310 Py_INCREF(Py_None);
2311 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002312}
2313#endif
2314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002315
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002316#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002317PyDoc_STRVAR(posix_popen__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002318"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002319Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002320
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002321#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002322#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002323static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002324async_system(const char *command)
2325{
2326 char *p, errormsg[256], args[1024];
2327 RESULTCODES rcodes;
2328 APIRET rc;
2329 char *shell = getenv("COMSPEC");
2330 if (!shell)
2331 shell = "cmd";
2332
2333 strcpy(args, shell);
2334 p = &args[ strlen(args)+1 ];
2335 strcpy(p, "/c ");
2336 strcat(p, command);
2337 p += strlen(p) + 1;
2338 *p = '\0';
2339
2340 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002341 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002342 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002343 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002344 &rcodes, shell);
2345 return rc;
2346}
2347
Guido van Rossumd48f2521997-12-05 22:19:34 +00002348static FILE *
2349popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002350{
2351 HFILE rhan, whan;
2352 FILE *retfd = NULL;
2353 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2354
Guido van Rossumd48f2521997-12-05 22:19:34 +00002355 if (rc != NO_ERROR) {
2356 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002357 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002358 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002359
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002360 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2361 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002362
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002363 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2364 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002365
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002366 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2367 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002368
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002369 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002370 }
2371
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002372 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2373 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002374
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002375 if (rc == NO_ERROR)
2376 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2377
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002378 close(oldfd); /* And Close Saved STDOUT Handle */
2379 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002380
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002381 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2382 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002383
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002384 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2385 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002386
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002387 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2388 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002389
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002390 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002391 }
2392
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002393 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2394 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002395
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002396 if (rc == NO_ERROR)
2397 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2398
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002399 close(oldfd); /* And Close Saved STDIN Handle */
2400 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002401
Guido van Rossumd48f2521997-12-05 22:19:34 +00002402 } else {
2403 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002404 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002405 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002406}
2407
2408static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002409posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002410{
2411 char *name;
2412 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002413 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002414 FILE *fp;
2415 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002416 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002417 return NULL;
2418 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002419 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002420 Py_END_ALLOW_THREADS
2421 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002422 return os2_error(err);
2423
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002424 f = PyFile_FromFile(fp, name, mode, fclose);
2425 if (f != NULL)
2426 PyFile_SetBufSize(f, bufsize);
2427 return f;
2428}
2429
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002430#elif defined(PYCC_GCC)
2431
2432/* standard posix version of popen() support */
2433static PyObject *
2434posix_popen(PyObject *self, PyObject *args)
2435{
2436 char *name;
2437 char *mode = "r";
2438 int bufsize = -1;
2439 FILE *fp;
2440 PyObject *f;
2441 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2442 return NULL;
2443 Py_BEGIN_ALLOW_THREADS
2444 fp = popen(name, mode);
2445 Py_END_ALLOW_THREADS
2446 if (fp == NULL)
2447 return posix_error();
2448 f = PyFile_FromFile(fp, name, mode, pclose);
2449 if (f != NULL)
2450 PyFile_SetBufSize(f, bufsize);
2451 return f;
2452}
2453
2454/* fork() under OS/2 has lots'o'warts
2455 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2456 * most of this code is a ripoff of the win32 code, but using the
2457 * capabilities of EMX's C library routines
2458 */
2459
2460/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2461#define POPEN_1 1
2462#define POPEN_2 2
2463#define POPEN_3 3
2464#define POPEN_4 4
2465
2466static PyObject *_PyPopen(char *, int, int, int);
2467static int _PyPclose(FILE *file);
2468
2469/*
2470 * Internal dictionary mapping popen* file pointers to process handles,
2471 * for use when retrieving the process exit code. See _PyPclose() below
2472 * for more information on this dictionary's use.
2473 */
2474static PyObject *_PyPopenProcs = NULL;
2475
2476/* os2emx version of popen2()
2477 *
2478 * The result of this function is a pipe (file) connected to the
2479 * process's stdin, and a pipe connected to the process's stdout.
2480 */
2481
2482static PyObject *
2483os2emx_popen2(PyObject *self, PyObject *args)
2484{
2485 PyObject *f;
2486 int tm=0;
2487
2488 char *cmdstring;
2489 char *mode = "t";
2490 int bufsize = -1;
2491 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2492 return NULL;
2493
2494 if (*mode == 't')
2495 tm = O_TEXT;
2496 else if (*mode != 'b') {
2497 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2498 return NULL;
2499 } else
2500 tm = O_BINARY;
2501
2502 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2503
2504 return f;
2505}
2506
2507/*
2508 * Variation on os2emx.popen2
2509 *
2510 * The result of this function is 3 pipes - the process's stdin,
2511 * stdout and stderr
2512 */
2513
2514static PyObject *
2515os2emx_popen3(PyObject *self, PyObject *args)
2516{
2517 PyObject *f;
2518 int tm = 0;
2519
2520 char *cmdstring;
2521 char *mode = "t";
2522 int bufsize = -1;
2523 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2524 return NULL;
2525
2526 if (*mode == 't')
2527 tm = O_TEXT;
2528 else if (*mode != 'b') {
2529 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2530 return NULL;
2531 } else
2532 tm = O_BINARY;
2533
2534 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2535
2536 return f;
2537}
2538
2539/*
2540 * Variation on os2emx.popen2
2541 *
2542 * The result of this function is 2 pipes - the processes stdin,
2543 * and stdout+stderr combined as a single pipe.
2544 */
2545
2546static PyObject *
2547os2emx_popen4(PyObject *self, PyObject *args)
2548{
2549 PyObject *f;
2550 int tm = 0;
2551
2552 char *cmdstring;
2553 char *mode = "t";
2554 int bufsize = -1;
2555 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2556 return NULL;
2557
2558 if (*mode == 't')
2559 tm = O_TEXT;
2560 else if (*mode != 'b') {
2561 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2562 return NULL;
2563 } else
2564 tm = O_BINARY;
2565
2566 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2567
2568 return f;
2569}
2570
2571/* a couple of structures for convenient handling of multiple
2572 * file handles and pipes
2573 */
2574struct file_ref
2575{
2576 int handle;
2577 int flags;
2578};
2579
2580struct pipe_ref
2581{
2582 int rd;
2583 int wr;
2584};
2585
2586/* The following code is derived from the win32 code */
2587
2588static PyObject *
2589_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2590{
2591 struct file_ref stdio[3];
2592 struct pipe_ref p_fd[3];
2593 FILE *p_s[3];
2594 int file_count, i, pipe_err, pipe_pid;
2595 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2596 PyObject *f, *p_f[3];
2597
2598 /* file modes for subsequent fdopen's on pipe handles */
2599 if (mode == O_TEXT)
2600 {
2601 rd_mode = "rt";
2602 wr_mode = "wt";
2603 }
2604 else
2605 {
2606 rd_mode = "rb";
2607 wr_mode = "wb";
2608 }
2609
2610 /* prepare shell references */
2611 if ((shell = getenv("EMXSHELL")) == NULL)
2612 if ((shell = getenv("COMSPEC")) == NULL)
2613 {
2614 errno = ENOENT;
2615 return posix_error();
2616 }
2617
2618 sh_name = _getname(shell);
2619 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2620 opt = "/c";
2621 else
2622 opt = "-c";
2623
2624 /* save current stdio fds + their flags, and set not inheritable */
2625 i = pipe_err = 0;
2626 while (pipe_err >= 0 && i < 3)
2627 {
2628 pipe_err = stdio[i].handle = dup(i);
2629 stdio[i].flags = fcntl(i, F_GETFD, 0);
2630 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2631 i++;
2632 }
2633 if (pipe_err < 0)
2634 {
2635 /* didn't get them all saved - clean up and bail out */
2636 int saved_err = errno;
2637 while (i-- > 0)
2638 {
2639 close(stdio[i].handle);
2640 }
2641 errno = saved_err;
2642 return posix_error();
2643 }
2644
2645 /* create pipe ends */
2646 file_count = 2;
2647 if (n == POPEN_3)
2648 file_count = 3;
2649 i = pipe_err = 0;
2650 while ((pipe_err == 0) && (i < file_count))
2651 pipe_err = pipe((int *)&p_fd[i++]);
2652 if (pipe_err < 0)
2653 {
2654 /* didn't get them all made - clean up and bail out */
2655 while (i-- > 0)
2656 {
2657 close(p_fd[i].wr);
2658 close(p_fd[i].rd);
2659 }
2660 errno = EPIPE;
2661 return posix_error();
2662 }
2663
2664 /* change the actual standard IO streams over temporarily,
2665 * making the retained pipe ends non-inheritable
2666 */
2667 pipe_err = 0;
2668
2669 /* - stdin */
2670 if (dup2(p_fd[0].rd, 0) == 0)
2671 {
2672 close(p_fd[0].rd);
2673 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2674 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2675 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2676 {
2677 close(p_fd[0].wr);
2678 pipe_err = -1;
2679 }
2680 }
2681 else
2682 {
2683 pipe_err = -1;
2684 }
2685
2686 /* - stdout */
2687 if (pipe_err == 0)
2688 {
2689 if (dup2(p_fd[1].wr, 1) == 1)
2690 {
2691 close(p_fd[1].wr);
2692 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2693 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2694 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2695 {
2696 close(p_fd[1].rd);
2697 pipe_err = -1;
2698 }
2699 }
2700 else
2701 {
2702 pipe_err = -1;
2703 }
2704 }
2705
2706 /* - stderr, as required */
2707 if (pipe_err == 0)
2708 switch (n)
2709 {
2710 case POPEN_3:
2711 {
2712 if (dup2(p_fd[2].wr, 2) == 2)
2713 {
2714 close(p_fd[2].wr);
2715 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2716 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2717 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2718 {
2719 close(p_fd[2].rd);
2720 pipe_err = -1;
2721 }
2722 }
2723 else
2724 {
2725 pipe_err = -1;
2726 }
2727 break;
2728 }
2729
2730 case POPEN_4:
2731 {
2732 if (dup2(1, 2) != 2)
2733 {
2734 pipe_err = -1;
2735 }
2736 break;
2737 }
2738 }
2739
2740 /* spawn the child process */
2741 if (pipe_err == 0)
2742 {
2743 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2744 if (pipe_pid == -1)
2745 {
2746 pipe_err = -1;
2747 }
2748 else
2749 {
2750 /* save the PID into the FILE structure
2751 * NOTE: this implementation doesn't actually
2752 * take advantage of this, but do it for
2753 * completeness - AIM Apr01
2754 */
2755 for (i = 0; i < file_count; i++)
2756 p_s[i]->_pid = pipe_pid;
2757 }
2758 }
2759
2760 /* reset standard IO to normal */
2761 for (i = 0; i < 3; i++)
2762 {
2763 dup2(stdio[i].handle, i);
2764 fcntl(i, F_SETFD, stdio[i].flags);
2765 close(stdio[i].handle);
2766 }
2767
2768 /* if any remnant problems, clean up and bail out */
2769 if (pipe_err < 0)
2770 {
2771 for (i = 0; i < 3; i++)
2772 {
2773 close(p_fd[i].rd);
2774 close(p_fd[i].wr);
2775 }
2776 errno = EPIPE;
2777 return posix_error_with_filename(cmdstring);
2778 }
2779
2780 /* build tuple of file objects to return */
2781 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2782 PyFile_SetBufSize(p_f[0], bufsize);
2783 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2784 PyFile_SetBufSize(p_f[1], bufsize);
2785 if (n == POPEN_3)
2786 {
2787 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2788 PyFile_SetBufSize(p_f[0], bufsize);
2789 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2790 }
2791 else
2792 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2793
2794 /*
2795 * Insert the files we've created into the process dictionary
2796 * all referencing the list with the process handle and the
2797 * initial number of files (see description below in _PyPclose).
2798 * Since if _PyPclose later tried to wait on a process when all
2799 * handles weren't closed, it could create a deadlock with the
2800 * child, we spend some energy here to try to ensure that we
2801 * either insert all file handles into the dictionary or none
2802 * at all. It's a little clumsy with the various popen modes
2803 * and variable number of files involved.
2804 */
2805 if (!_PyPopenProcs)
2806 {
2807 _PyPopenProcs = PyDict_New();
2808 }
2809
2810 if (_PyPopenProcs)
2811 {
2812 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2813 int ins_rc[3];
2814
2815 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2816 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2817
2818 procObj = PyList_New(2);
2819 pidObj = PyInt_FromLong((long) pipe_pid);
2820 intObj = PyInt_FromLong((long) file_count);
2821
2822 if (procObj && pidObj && intObj)
2823 {
2824 PyList_SetItem(procObj, 0, pidObj);
2825 PyList_SetItem(procObj, 1, intObj);
2826
2827 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2828 if (fileObj[0])
2829 {
2830 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2831 fileObj[0],
2832 procObj);
2833 }
2834 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2835 if (fileObj[1])
2836 {
2837 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2838 fileObj[1],
2839 procObj);
2840 }
2841 if (file_count >= 3)
2842 {
2843 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2844 if (fileObj[2])
2845 {
2846 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2847 fileObj[2],
2848 procObj);
2849 }
2850 }
2851
2852 if (ins_rc[0] < 0 || !fileObj[0] ||
2853 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2854 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2855 {
2856 /* Something failed - remove any dictionary
2857 * entries that did make it.
2858 */
2859 if (!ins_rc[0] && fileObj[0])
2860 {
2861 PyDict_DelItem(_PyPopenProcs,
2862 fileObj[0]);
2863 }
2864 if (!ins_rc[1] && fileObj[1])
2865 {
2866 PyDict_DelItem(_PyPopenProcs,
2867 fileObj[1]);
2868 }
2869 if (!ins_rc[2] && fileObj[2])
2870 {
2871 PyDict_DelItem(_PyPopenProcs,
2872 fileObj[2]);
2873 }
2874 }
2875 }
2876
2877 /*
2878 * Clean up our localized references for the dictionary keys
2879 * and value since PyDict_SetItem will Py_INCREF any copies
2880 * that got placed in the dictionary.
2881 */
2882 Py_XDECREF(procObj);
2883 Py_XDECREF(fileObj[0]);
2884 Py_XDECREF(fileObj[1]);
2885 Py_XDECREF(fileObj[2]);
2886 }
2887
2888 /* Child is launched. */
2889 return f;
2890}
2891
2892/*
2893 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2894 * exit code for the child process and return as a result of the close.
2895 *
2896 * This function uses the _PyPopenProcs dictionary in order to map the
2897 * input file pointer to information about the process that was
2898 * originally created by the popen* call that created the file pointer.
2899 * The dictionary uses the file pointer as a key (with one entry
2900 * inserted for each file returned by the original popen* call) and a
2901 * single list object as the value for all files from a single call.
2902 * The list object contains the Win32 process handle at [0], and a file
2903 * count at [1], which is initialized to the total number of file
2904 * handles using that list.
2905 *
2906 * This function closes whichever handle it is passed, and decrements
2907 * the file count in the dictionary for the process handle pointed to
2908 * by this file. On the last close (when the file count reaches zero),
2909 * this function will wait for the child process and then return its
2910 * exit code as the result of the close() operation. This permits the
2911 * files to be closed in any order - it is always the close() of the
2912 * final handle that will return the exit code.
2913 */
2914
2915 /* RED_FLAG 31-Aug-2000 Tim
2916 * This is always called (today!) between a pair of
2917 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2918 * macros. So the thread running this has no valid thread state, as
2919 * far as Python is concerned. However, this calls some Python API
2920 * functions that cannot be called safely without a valid thread
2921 * state, in particular PyDict_GetItem.
2922 * As a temporary hack (although it may last for years ...), we
2923 * *rely* on not having a valid thread state in this function, in
2924 * order to create our own "from scratch".
2925 * This will deadlock if _PyPclose is ever called by a thread
2926 * holding the global lock.
2927 * (The OS/2 EMX thread support appears to cover the case where the
2928 * lock is already held - AIM Apr01)
2929 */
2930
2931static int _PyPclose(FILE *file)
2932{
2933 int result;
2934 int exit_code;
2935 int pipe_pid;
2936 PyObject *procObj, *pidObj, *intObj, *fileObj;
2937 int file_count;
2938#ifdef WITH_THREAD
2939 PyInterpreterState* pInterpreterState;
2940 PyThreadState* pThreadState;
2941#endif
2942
2943 /* Close the file handle first, to ensure it can't block the
2944 * child from exiting if it's the last handle.
2945 */
2946 result = fclose(file);
2947
2948#ifdef WITH_THREAD
2949 /* Bootstrap a valid thread state into existence. */
2950 pInterpreterState = PyInterpreterState_New();
2951 if (!pInterpreterState) {
2952 /* Well, we're hosed now! We don't have a thread
2953 * state, so can't call a nice error routine, or raise
2954 * an exception. Just die.
2955 */
2956 Py_FatalError("unable to allocate interpreter state "
2957 "when closing popen object.");
2958 return -1; /* unreachable */
2959 }
2960 pThreadState = PyThreadState_New(pInterpreterState);
2961 if (!pThreadState) {
2962 Py_FatalError("unable to allocate thread state "
2963 "when closing popen object.");
2964 return -1; /* unreachable */
2965 }
2966 /* Grab the global lock. Note that this will deadlock if the
2967 * current thread already has the lock! (see RED_FLAG comments
2968 * before this function)
2969 */
2970 PyEval_RestoreThread(pThreadState);
2971#endif
2972
2973 if (_PyPopenProcs)
2974 {
2975 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2976 (procObj = PyDict_GetItem(_PyPopenProcs,
2977 fileObj)) != NULL &&
2978 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2979 (intObj = PyList_GetItem(procObj,1)) != NULL)
2980 {
2981 pipe_pid = (int) PyInt_AsLong(pidObj);
2982 file_count = (int) PyInt_AsLong(intObj);
2983
2984 if (file_count > 1)
2985 {
2986 /* Still other files referencing process */
2987 file_count--;
2988 PyList_SetItem(procObj,1,
2989 PyInt_FromLong((long) file_count));
2990 }
2991 else
2992 {
2993 /* Last file for this process */
2994 if (result != EOF &&
2995 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2996 {
2997 /* extract exit status */
2998 if (WIFEXITED(exit_code))
2999 {
3000 result = WEXITSTATUS(exit_code);
3001 }
3002 else
3003 {
3004 errno = EPIPE;
3005 result = -1;
3006 }
3007 }
3008 else
3009 {
3010 /* Indicate failure - this will cause the file object
3011 * to raise an I/O error and translate the last
3012 * error code from errno. We do have a problem with
3013 * last errors that overlap the normal errno table,
3014 * but that's a consistent problem with the file object.
3015 */
3016 result = -1;
3017 }
3018 }
3019
3020 /* Remove this file pointer from dictionary */
3021 PyDict_DelItem(_PyPopenProcs, fileObj);
3022
3023 if (PyDict_Size(_PyPopenProcs) == 0)
3024 {
3025 Py_DECREF(_PyPopenProcs);
3026 _PyPopenProcs = NULL;
3027 }
3028
3029 } /* if object retrieval ok */
3030
3031 Py_XDECREF(fileObj);
3032 } /* if _PyPopenProcs */
3033
3034#ifdef WITH_THREAD
3035 /* Tear down the thread & interpreter states.
3036 * Note that interpreter state clear & delete functions automatically
3037 * call the thread clear & delete functions, and indeed insist on
3038 * doing that themselves. The lock must be held during the clear, but
3039 * need not be held during the delete.
3040 */
3041 PyInterpreterState_Clear(pInterpreterState);
3042 PyEval_ReleaseThread(pThreadState);
3043 PyInterpreterState_Delete(pInterpreterState);
3044#endif
3045
3046 return result;
3047}
3048
3049#endif /* PYCC_??? */
3050
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003051#elif defined(MS_WIN32)
3052
3053/*
3054 * Portable 'popen' replacement for Win32.
3055 *
3056 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3057 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003058 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003059 */
3060
3061#include <malloc.h>
3062#include <io.h>
3063#include <fcntl.h>
3064
3065/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3066#define POPEN_1 1
3067#define POPEN_2 2
3068#define POPEN_3 3
3069#define POPEN_4 4
3070
3071static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003072static int _PyPclose(FILE *file);
3073
3074/*
3075 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003076 * for use when retrieving the process exit code. See _PyPclose() below
3077 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003078 */
3079static PyObject *_PyPopenProcs = NULL;
3080
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003081
3082/* popen that works from a GUI.
3083 *
3084 * The result of this function is a pipe (file) connected to the
3085 * processes stdin or stdout, depending on the requested mode.
3086 */
3087
3088static PyObject *
3089posix_popen(PyObject *self, PyObject *args)
3090{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003091 PyObject *f, *s;
3092 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003093
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003094 char *cmdstring;
3095 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003096 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003097 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003098 return NULL;
3099
3100 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003101
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003102 if (*mode == 'r')
3103 tm = _O_RDONLY;
3104 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003105 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003106 return NULL;
3107 } else
3108 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003109
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003110 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003111 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003112 return NULL;
3113 }
3114
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003115 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003116 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003117 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003118 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003119 else
3120 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3121
3122 return f;
3123}
3124
3125/* Variation on win32pipe.popen
3126 *
3127 * The result of this function is a pipe (file) connected to the
3128 * process's stdin, and a pipe connected to the process's stdout.
3129 */
3130
3131static PyObject *
3132win32_popen2(PyObject *self, PyObject *args)
3133{
3134 PyObject *f;
3135 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003136
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003137 char *cmdstring;
3138 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003139 int bufsize = -1;
3140 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003141 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003142
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003143 if (*mode == 't')
3144 tm = _O_TEXT;
3145 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003146 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003147 return NULL;
3148 } else
3149 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003150
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003151 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003152 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003153 return NULL;
3154 }
3155
3156 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003157
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003158 return f;
3159}
3160
3161/*
3162 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003163 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003164 * The result of this function is 3 pipes - the process's stdin,
3165 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003166 */
3167
3168static PyObject *
3169win32_popen3(PyObject *self, PyObject *args)
3170{
3171 PyObject *f;
3172 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003173
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003174 char *cmdstring;
3175 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003176 int bufsize = -1;
3177 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003178 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003179
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003180 if (*mode == 't')
3181 tm = _O_TEXT;
3182 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003183 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003184 return NULL;
3185 } else
3186 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003187
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003188 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003189 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003190 return NULL;
3191 }
3192
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003193 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003194
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003195 return f;
3196}
3197
3198/*
3199 * Variation on win32pipe.popen
3200 *
Tim Peters5aa91602002-01-30 05:46:57 +00003201 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003202 * and stdout+stderr combined as a single pipe.
3203 */
3204
3205static PyObject *
3206win32_popen4(PyObject *self, PyObject *args)
3207{
3208 PyObject *f;
3209 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003210
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003211 char *cmdstring;
3212 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003213 int bufsize = -1;
3214 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003215 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003216
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003217 if (*mode == 't')
3218 tm = _O_TEXT;
3219 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003220 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003221 return NULL;
3222 } else
3223 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003224
3225 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003226 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003227 return NULL;
3228 }
3229
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003230 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003231
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003232 return f;
3233}
3234
Mark Hammond08501372001-01-31 07:30:29 +00003235static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003236_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003237 HANDLE hStdin,
3238 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003239 HANDLE hStderr,
3240 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003241{
3242 PROCESS_INFORMATION piProcInfo;
3243 STARTUPINFO siStartInfo;
3244 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003245 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003246 int i;
3247 int x;
3248
3249 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003250 char *comshell;
3251
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003252 s1 = (char *)_alloca(i);
3253 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3254 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003255
3256 /* Explicitly check if we are using COMMAND.COM. If we are
3257 * then use the w9xpopen hack.
3258 */
3259 comshell = s1 + x;
3260 while (comshell >= s1 && *comshell != '\\')
3261 --comshell;
3262 ++comshell;
3263
3264 if (GetVersion() < 0x80000000 &&
3265 _stricmp(comshell, "command.com") != 0) {
3266 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003267 x = i + strlen(s3) + strlen(cmdstring) + 1;
3268 s2 = (char *)_alloca(x);
3269 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003270 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003271 }
3272 else {
3273 /*
Tim Peters402d5982001-08-27 06:37:48 +00003274 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3275 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003276 */
Mark Hammond08501372001-01-31 07:30:29 +00003277 char modulepath[_MAX_PATH];
3278 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003279 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3280 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003281 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003282 x = i+1;
3283 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003284 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003285 strncat(modulepath,
3286 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003287 (sizeof(modulepath)/sizeof(modulepath[0]))
3288 -strlen(modulepath));
3289 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003290 /* Eeek - file-not-found - possibly an embedding
3291 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003292 */
Tim Peters5aa91602002-01-30 05:46:57 +00003293 strncpy(modulepath,
3294 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003295 sizeof(modulepath)/sizeof(modulepath[0]));
3296 if (modulepath[strlen(modulepath)-1] != '\\')
3297 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003298 strncat(modulepath,
3299 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003300 (sizeof(modulepath)/sizeof(modulepath[0]))
3301 -strlen(modulepath));
3302 /* No where else to look - raise an easily identifiable
3303 error, rather than leaving Windows to report
3304 "file not found" - as the user is probably blissfully
3305 unaware this shim EXE is used, and it will confuse them.
3306 (well, it confused me for a while ;-)
3307 */
3308 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003309 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003310 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003311 "for popen to work with your shell "
3312 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003313 szConsoleSpawn);
3314 return FALSE;
3315 }
3316 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003317 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003318 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003319 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003320
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003321 s2 = (char *)_alloca(x);
3322 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003323 /* To maintain correct argument passing semantics,
3324 we pass the command-line as it stands, and allow
3325 quoting to be applied. w9xpopen.exe will then
3326 use its argv vector, and re-quote the necessary
3327 args for the ultimate child process.
3328 */
Tim Peters75cdad52001-11-28 22:07:30 +00003329 PyOS_snprintf(
3330 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003331 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003332 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003333 s1,
3334 s3,
3335 cmdstring);
3336 }
3337 }
3338
3339 /* Could be an else here to try cmd.exe / command.com in the path
3340 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003341 else {
Tim Peters402d5982001-08-27 06:37:48 +00003342 PyErr_SetString(PyExc_RuntimeError,
3343 "Cannot locate a COMSPEC environment variable to "
3344 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003345 return FALSE;
3346 }
Tim Peters5aa91602002-01-30 05:46:57 +00003347
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003348 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3349 siStartInfo.cb = sizeof(STARTUPINFO);
3350 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3351 siStartInfo.hStdInput = hStdin;
3352 siStartInfo.hStdOutput = hStdout;
3353 siStartInfo.hStdError = hStderr;
3354 siStartInfo.wShowWindow = SW_HIDE;
3355
3356 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003357 s2,
3358 NULL,
3359 NULL,
3360 TRUE,
3361 CREATE_NEW_CONSOLE,
3362 NULL,
3363 NULL,
3364 &siStartInfo,
3365 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003366 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003367 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003368
Mark Hammondb37a3732000-08-14 04:47:33 +00003369 /* Return process handle */
3370 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003371 return TRUE;
3372 }
Tim Peters402d5982001-08-27 06:37:48 +00003373 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003374 return FALSE;
3375}
3376
3377/* The following code is based off of KB: Q190351 */
3378
3379static PyObject *
3380_PyPopen(char *cmdstring, int mode, int n)
3381{
3382 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3383 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003384 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003385
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003386 SECURITY_ATTRIBUTES saAttr;
3387 BOOL fSuccess;
3388 int fd1, fd2, fd3;
3389 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003390 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003391 PyObject *f;
3392
3393 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3394 saAttr.bInheritHandle = TRUE;
3395 saAttr.lpSecurityDescriptor = NULL;
3396
3397 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3398 return win32_error("CreatePipe", NULL);
3399
3400 /* Create new output read handle and the input write handle. Set
3401 * the inheritance properties to FALSE. Otherwise, the child inherits
3402 * the these handles; resulting in non-closeable handles to the pipes
3403 * being created. */
3404 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003405 GetCurrentProcess(), &hChildStdinWrDup, 0,
3406 FALSE,
3407 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003408 if (!fSuccess)
3409 return win32_error("DuplicateHandle", NULL);
3410
3411 /* Close the inheritable version of ChildStdin
3412 that we're using. */
3413 CloseHandle(hChildStdinWr);
3414
3415 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3416 return win32_error("CreatePipe", NULL);
3417
3418 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003419 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3420 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003421 if (!fSuccess)
3422 return win32_error("DuplicateHandle", NULL);
3423
3424 /* Close the inheritable version of ChildStdout
3425 that we're using. */
3426 CloseHandle(hChildStdoutRd);
3427
3428 if (n != POPEN_4) {
3429 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3430 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003431 fSuccess = DuplicateHandle(GetCurrentProcess(),
3432 hChildStderrRd,
3433 GetCurrentProcess(),
3434 &hChildStderrRdDup, 0,
3435 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003436 if (!fSuccess)
3437 return win32_error("DuplicateHandle", NULL);
3438 /* Close the inheritable version of ChildStdErr that we're using. */
3439 CloseHandle(hChildStderrRd);
3440 }
Tim Peters5aa91602002-01-30 05:46:57 +00003441
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003442 switch (n) {
3443 case POPEN_1:
3444 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3445 case _O_WRONLY | _O_TEXT:
3446 /* Case for writing to child Stdin in text mode. */
3447 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3448 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003449 f = PyFile_FromFile(f1, cmdstring, "w", _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(hChildStdoutRdDup);
3453 CloseHandle(hChildStderrRdDup);
3454 break;
3455
3456 case _O_RDONLY | _O_TEXT:
3457 /* Case for reading from child Stdout in text mode. */
3458 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3459 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003460 f = PyFile_FromFile(f1, cmdstring, "r", _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(hChildStdinWrDup);
3464 CloseHandle(hChildStderrRdDup);
3465 break;
3466
3467 case _O_RDONLY | _O_BINARY:
3468 /* Case for readinig from child Stdout in binary mode. */
3469 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3470 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003471 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003472 PyFile_SetBufSize(f, 0);
3473 /* We don't care about these pipes anymore, so close them. */
3474 CloseHandle(hChildStdinWrDup);
3475 CloseHandle(hChildStderrRdDup);
3476 break;
3477
3478 case _O_WRONLY | _O_BINARY:
3479 /* Case for writing to child Stdin in binary mode. */
3480 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3481 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003482 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003483 PyFile_SetBufSize(f, 0);
3484 /* We don't care about these pipes anymore, so close them. */
3485 CloseHandle(hChildStdoutRdDup);
3486 CloseHandle(hChildStderrRdDup);
3487 break;
3488 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003489 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003490 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003491
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003492 case POPEN_2:
3493 case POPEN_4:
3494 {
3495 char *m1, *m2;
3496 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003497
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003498 if (mode && _O_TEXT) {
3499 m1 = "r";
3500 m2 = "w";
3501 } else {
3502 m1 = "rb";
3503 m2 = "wb";
3504 }
3505
3506 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3507 f1 = _fdopen(fd1, m2);
3508 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3509 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003510 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003511 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003512 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003513 PyFile_SetBufSize(p2, 0);
3514
3515 if (n != 4)
3516 CloseHandle(hChildStderrRdDup);
3517
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003518 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003519 Py_XDECREF(p1);
3520 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003521 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003522 break;
3523 }
Tim Peters5aa91602002-01-30 05:46:57 +00003524
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003525 case POPEN_3:
3526 {
3527 char *m1, *m2;
3528 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003529
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003530 if (mode && _O_TEXT) {
3531 m1 = "r";
3532 m2 = "w";
3533 } else {
3534 m1 = "rb";
3535 m2 = "wb";
3536 }
3537
3538 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3539 f1 = _fdopen(fd1, m2);
3540 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3541 f2 = _fdopen(fd2, m1);
3542 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3543 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003544 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003545 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3546 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003547 PyFile_SetBufSize(p1, 0);
3548 PyFile_SetBufSize(p2, 0);
3549 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003550 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003551 Py_XDECREF(p1);
3552 Py_XDECREF(p2);
3553 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003554 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003555 break;
3556 }
3557 }
3558
3559 if (n == POPEN_4) {
3560 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003561 hChildStdinRd,
3562 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003563 hChildStdoutWr,
3564 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003565 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003566 }
3567 else {
3568 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003569 hChildStdinRd,
3570 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003571 hChildStderrWr,
3572 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003573 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003574 }
3575
Mark Hammondb37a3732000-08-14 04:47:33 +00003576 /*
3577 * Insert the files we've created into the process dictionary
3578 * all referencing the list with the process handle and the
3579 * initial number of files (see description below in _PyPclose).
3580 * Since if _PyPclose later tried to wait on a process when all
3581 * handles weren't closed, it could create a deadlock with the
3582 * child, we spend some energy here to try to ensure that we
3583 * either insert all file handles into the dictionary or none
3584 * at all. It's a little clumsy with the various popen modes
3585 * and variable number of files involved.
3586 */
3587 if (!_PyPopenProcs) {
3588 _PyPopenProcs = PyDict_New();
3589 }
3590
3591 if (_PyPopenProcs) {
3592 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3593 int ins_rc[3];
3594
3595 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3596 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3597
3598 procObj = PyList_New(2);
3599 hProcessObj = PyLong_FromVoidPtr(hProcess);
3600 intObj = PyInt_FromLong(file_count);
3601
3602 if (procObj && hProcessObj && intObj) {
3603 PyList_SetItem(procObj,0,hProcessObj);
3604 PyList_SetItem(procObj,1,intObj);
3605
3606 fileObj[0] = PyLong_FromVoidPtr(f1);
3607 if (fileObj[0]) {
3608 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3609 fileObj[0],
3610 procObj);
3611 }
3612 if (file_count >= 2) {
3613 fileObj[1] = PyLong_FromVoidPtr(f2);
3614 if (fileObj[1]) {
3615 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3616 fileObj[1],
3617 procObj);
3618 }
3619 }
3620 if (file_count >= 3) {
3621 fileObj[2] = PyLong_FromVoidPtr(f3);
3622 if (fileObj[2]) {
3623 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3624 fileObj[2],
3625 procObj);
3626 }
3627 }
3628
3629 if (ins_rc[0] < 0 || !fileObj[0] ||
3630 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3631 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3632 /* Something failed - remove any dictionary
3633 * entries that did make it.
3634 */
3635 if (!ins_rc[0] && fileObj[0]) {
3636 PyDict_DelItem(_PyPopenProcs,
3637 fileObj[0]);
3638 }
3639 if (!ins_rc[1] && fileObj[1]) {
3640 PyDict_DelItem(_PyPopenProcs,
3641 fileObj[1]);
3642 }
3643 if (!ins_rc[2] && fileObj[2]) {
3644 PyDict_DelItem(_PyPopenProcs,
3645 fileObj[2]);
3646 }
3647 }
3648 }
Tim Peters5aa91602002-01-30 05:46:57 +00003649
Mark Hammondb37a3732000-08-14 04:47:33 +00003650 /*
3651 * Clean up our localized references for the dictionary keys
3652 * and value since PyDict_SetItem will Py_INCREF any copies
3653 * that got placed in the dictionary.
3654 */
3655 Py_XDECREF(procObj);
3656 Py_XDECREF(fileObj[0]);
3657 Py_XDECREF(fileObj[1]);
3658 Py_XDECREF(fileObj[2]);
3659 }
3660
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003661 /* Child is launched. Close the parents copy of those pipe
3662 * handles that only the child should have open. You need to
3663 * make sure that no handles to the write end of the output pipe
3664 * are maintained in this process or else the pipe will not close
3665 * when the child process exits and the ReadFile will hang. */
3666
3667 if (!CloseHandle(hChildStdinRd))
3668 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003669
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003670 if (!CloseHandle(hChildStdoutWr))
3671 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003672
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003673 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3674 return win32_error("CloseHandle", NULL);
3675
3676 return f;
3677}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003678
3679/*
3680 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3681 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003682 *
3683 * This function uses the _PyPopenProcs dictionary in order to map the
3684 * input file pointer to information about the process that was
3685 * originally created by the popen* call that created the file pointer.
3686 * The dictionary uses the file pointer as a key (with one entry
3687 * inserted for each file returned by the original popen* call) and a
3688 * single list object as the value for all files from a single call.
3689 * The list object contains the Win32 process handle at [0], and a file
3690 * count at [1], which is initialized to the total number of file
3691 * handles using that list.
3692 *
3693 * This function closes whichever handle it is passed, and decrements
3694 * the file count in the dictionary for the process handle pointed to
3695 * by this file. On the last close (when the file count reaches zero),
3696 * this function will wait for the child process and then return its
3697 * exit code as the result of the close() operation. This permits the
3698 * files to be closed in any order - it is always the close() of the
3699 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003700 */
Tim Peters736aa322000-09-01 06:51:24 +00003701
3702 /* RED_FLAG 31-Aug-2000 Tim
3703 * This is always called (today!) between a pair of
3704 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3705 * macros. So the thread running this has no valid thread state, as
3706 * far as Python is concerned. However, this calls some Python API
3707 * functions that cannot be called safely without a valid thread
3708 * state, in particular PyDict_GetItem.
3709 * As a temporary hack (although it may last for years ...), we
3710 * *rely* on not having a valid thread state in this function, in
3711 * order to create our own "from scratch".
3712 * This will deadlock if _PyPclose is ever called by a thread
3713 * holding the global lock.
3714 */
3715
Fredrik Lundh56055a42000-07-23 19:47:12 +00003716static int _PyPclose(FILE *file)
3717{
Fredrik Lundh20318932000-07-26 17:29:12 +00003718 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003719 DWORD exit_code;
3720 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003721 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3722 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003723#ifdef WITH_THREAD
3724 PyInterpreterState* pInterpreterState;
3725 PyThreadState* pThreadState;
3726#endif
3727
Fredrik Lundh20318932000-07-26 17:29:12 +00003728 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003729 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003730 */
3731 result = fclose(file);
3732
Tim Peters736aa322000-09-01 06:51:24 +00003733#ifdef WITH_THREAD
3734 /* Bootstrap a valid thread state into existence. */
3735 pInterpreterState = PyInterpreterState_New();
3736 if (!pInterpreterState) {
3737 /* Well, we're hosed now! We don't have a thread
3738 * state, so can't call a nice error routine, or raise
3739 * an exception. Just die.
3740 */
3741 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003742 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003743 return -1; /* unreachable */
3744 }
3745 pThreadState = PyThreadState_New(pInterpreterState);
3746 if (!pThreadState) {
3747 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003748 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003749 return -1; /* unreachable */
3750 }
3751 /* Grab the global lock. Note that this will deadlock if the
3752 * current thread already has the lock! (see RED_FLAG comments
3753 * before this function)
3754 */
3755 PyEval_RestoreThread(pThreadState);
3756#endif
3757
Fredrik Lundh56055a42000-07-23 19:47:12 +00003758 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003759 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3760 (procObj = PyDict_GetItem(_PyPopenProcs,
3761 fileObj)) != NULL &&
3762 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3763 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3764
3765 hProcess = PyLong_AsVoidPtr(hProcessObj);
3766 file_count = PyInt_AsLong(intObj);
3767
3768 if (file_count > 1) {
3769 /* Still other files referencing process */
3770 file_count--;
3771 PyList_SetItem(procObj,1,
3772 PyInt_FromLong(file_count));
3773 } else {
3774 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003775 if (result != EOF &&
3776 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3777 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003778 /* Possible truncation here in 16-bit environments, but
3779 * real exit codes are just the lower byte in any event.
3780 */
3781 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003782 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003783 /* Indicate failure - this will cause the file object
3784 * to raise an I/O error and translate the last Win32
3785 * error code from errno. We do have a problem with
3786 * last errors that overlap the normal errno table,
3787 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003788 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003789 if (result != EOF) {
3790 /* If the error wasn't from the fclose(), then
3791 * set errno for the file object error handling.
3792 */
3793 errno = GetLastError();
3794 }
3795 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003796 }
3797
3798 /* Free up the native handle at this point */
3799 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003800 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003801
Mark Hammondb37a3732000-08-14 04:47:33 +00003802 /* Remove this file pointer from dictionary */
3803 PyDict_DelItem(_PyPopenProcs, fileObj);
3804
3805 if (PyDict_Size(_PyPopenProcs) == 0) {
3806 Py_DECREF(_PyPopenProcs);
3807 _PyPopenProcs = NULL;
3808 }
3809
3810 } /* if object retrieval ok */
3811
3812 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003813 } /* if _PyPopenProcs */
3814
Tim Peters736aa322000-09-01 06:51:24 +00003815#ifdef WITH_THREAD
3816 /* Tear down the thread & interpreter states.
3817 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003818 * call the thread clear & delete functions, and indeed insist on
3819 * doing that themselves. The lock must be held during the clear, but
3820 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003821 */
3822 PyInterpreterState_Clear(pInterpreterState);
3823 PyEval_ReleaseThread(pThreadState);
3824 PyInterpreterState_Delete(pInterpreterState);
3825#endif
3826
Fredrik Lundh56055a42000-07-23 19:47:12 +00003827 return result;
3828}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003829
3830#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003832posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003833{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003834 char *name;
3835 char *mode = "r";
3836 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003837 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003838 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003839 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003840 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003841 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003842 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003843 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003844 if (fp == NULL)
3845 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003846 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003847 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003848 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003849 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003850}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003851
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003852#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003853#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003855
Guido van Rossumb6775db1994-08-01 11:34:53 +00003856#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003857PyDoc_STRVAR(posix_setuid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003858"setuid(uid) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003859Set the current process's user id.");
3860
Barry Warsaw53699e91996-12-10 23:23:01 +00003861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003862posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003863{
3864 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003865 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003866 return NULL;
3867 if (setuid(uid) < 0)
3868 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003869 Py_INCREF(Py_None);
3870 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003871}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003872#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003873
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003874
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003875#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003876PyDoc_STRVAR(posix_seteuid__doc__,
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003877"seteuid(uid) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003878Set the current process's effective user id.");
3879
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003880static PyObject *
3881posix_seteuid (PyObject *self, PyObject *args)
3882{
3883 int euid;
3884 if (!PyArg_ParseTuple(args, "i", &euid)) {
3885 return NULL;
3886 } else if (seteuid(euid) < 0) {
3887 return posix_error();
3888 } else {
3889 Py_INCREF(Py_None);
3890 return Py_None;
3891 }
3892}
3893#endif /* HAVE_SETEUID */
3894
3895#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003896PyDoc_STRVAR(posix_setegid__doc__,
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003897"setegid(gid) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898Set the current process's effective group id.");
3899
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003900static PyObject *
3901posix_setegid (PyObject *self, PyObject *args)
3902{
3903 int egid;
3904 if (!PyArg_ParseTuple(args, "i", &egid)) {
3905 return NULL;
3906 } else if (setegid(egid) < 0) {
3907 return posix_error();
3908 } else {
3909 Py_INCREF(Py_None);
3910 return Py_None;
3911 }
3912}
3913#endif /* HAVE_SETEGID */
3914
3915#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003916PyDoc_STRVAR(posix_setreuid__doc__,
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003917"seteuid(ruid, euid) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003918Set the current process's real and effective user ids.");
3919
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003920static PyObject *
3921posix_setreuid (PyObject *self, PyObject *args)
3922{
3923 int ruid, euid;
3924 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3925 return NULL;
3926 } else if (setreuid(ruid, euid) < 0) {
3927 return posix_error();
3928 } else {
3929 Py_INCREF(Py_None);
3930 return Py_None;
3931 }
3932}
3933#endif /* HAVE_SETREUID */
3934
3935#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003936PyDoc_STRVAR(posix_setregid__doc__,
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003937"setegid(rgid, egid) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003938Set the current process's real and effective group ids.");
3939
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003940static PyObject *
3941posix_setregid (PyObject *self, PyObject *args)
3942{
3943 int rgid, egid;
3944 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3945 return NULL;
3946 } else if (setregid(rgid, egid) < 0) {
3947 return posix_error();
3948 } else {
3949 Py_INCREF(Py_None);
3950 return Py_None;
3951 }
3952}
3953#endif /* HAVE_SETREGID */
3954
Guido van Rossumb6775db1994-08-01 11:34:53 +00003955#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003956PyDoc_STRVAR(posix_setgid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003957"setgid(gid) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003958Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003959
Barry Warsaw53699e91996-12-10 23:23:01 +00003960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003961posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003962{
3963 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003964 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003965 return NULL;
3966 if (setgid(gid) < 0)
3967 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003968 Py_INCREF(Py_None);
3969 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003970}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003971#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003972
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003973#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003974PyDoc_STRVAR(posix_setgroups__doc__,
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003975"setgroups(list) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003976Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003977
3978static PyObject *
3979posix_setgroups(PyObject *self, PyObject *args)
3980{
3981 PyObject *groups;
3982 int i, len;
3983 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003984
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003985 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3986 return NULL;
3987 if (!PySequence_Check(groups)) {
3988 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3989 return NULL;
3990 }
3991 len = PySequence_Size(groups);
3992 if (len > MAX_GROUPS) {
3993 PyErr_SetString(PyExc_ValueError, "too many groups");
3994 return NULL;
3995 }
3996 for(i = 0; i < len; i++) {
3997 PyObject *elem;
3998 elem = PySequence_GetItem(groups, i);
3999 if (!elem)
4000 return NULL;
4001 if (!PyInt_Check(elem)) {
4002 PyErr_SetString(PyExc_TypeError,
4003 "groups must be integers");
4004 Py_DECREF(elem);
4005 return NULL;
4006 }
4007 /* XXX: check that value fits into gid_t. */
4008 grouplist[i] = PyInt_AsLong(elem);
4009 Py_DECREF(elem);
4010 }
4011
4012 if (setgroups(len, grouplist) < 0)
4013 return posix_error();
4014 Py_INCREF(Py_None);
4015 return Py_None;
4016}
4017#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004018
Guido van Rossumb6775db1994-08-01 11:34:53 +00004019#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004020PyDoc_STRVAR(posix_waitpid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004021"waitpid(pid, options) -> (pid, status)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004022Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004023
Barry Warsaw53699e91996-12-10 23:23:01 +00004024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004025posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004026{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004027 int pid, options;
4028#ifdef UNION_WAIT
4029 union wait status;
4030#define status_i (status.w_status)
4031#else
4032 int status;
4033#define status_i status
4034#endif
4035 status_i = 0;
4036
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004037 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004038 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004039 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004040 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004041 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004042 if (pid == -1)
4043 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004044 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004045 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004046}
4047
Tim Petersab034fa2002-02-01 11:27:43 +00004048#elif defined(HAVE_CWAIT)
4049
4050/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004051PyDoc_STRVAR(posix_waitpid__doc__,
Tim Petersab034fa2002-02-01 11:27:43 +00004052"waitpid(pid, options) -> (pid, status << 8)\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004053"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004054
4055static PyObject *
4056posix_waitpid(PyObject *self, PyObject *args)
4057{
4058 int pid, options;
4059 int status;
4060
4061 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4062 return NULL;
4063 Py_BEGIN_ALLOW_THREADS
4064 pid = _cwait(&status, pid, options);
4065 Py_END_ALLOW_THREADS
4066 if (pid == -1)
4067 return posix_error();
4068 else
4069 /* shift the status left a byte so this is more like the
4070 POSIX waitpid */
4071 return Py_BuildValue("ii", pid, status << 8);
4072}
4073#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004074
Guido van Rossumad0ee831995-03-01 10:34:45 +00004075#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004076PyDoc_STRVAR(posix_wait__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004077"wait() -> (pid, status)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004078Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004079
Barry Warsaw53699e91996-12-10 23:23:01 +00004080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004081posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004082{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004083 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004084#ifdef UNION_WAIT
4085 union wait status;
4086#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004087#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004088 int status;
4089#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004090#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004091 if (!PyArg_ParseTuple(args, ":wait"))
4092 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004093 status_i = 0;
4094 Py_BEGIN_ALLOW_THREADS
4095 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004096 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004097 if (pid == -1)
4098 return posix_error();
4099 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004100 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004101#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004102}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004103#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004104
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004105
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004106PyDoc_STRVAR(posix_lstat__doc__,
Fred Drake193a3f62002-03-12 21:38:49 +00004107"lstat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,\n\
4108 st_size, st_atime, st_mtime, st_ctime)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004109Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004110
Barry Warsaw53699e91996-12-10 23:23:01 +00004111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004112posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004113{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004114#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004115 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004116#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004117 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004118#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004119}
4120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004121
Guido van Rossumb6775db1994-08-01 11:34:53 +00004122#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004123PyDoc_STRVAR(posix_readlink__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004124"readlink(path) -> path\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004125Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004126
Barry Warsaw53699e91996-12-10 23:23:01 +00004127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004128posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004129{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004130 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004131 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004132 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004133 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004134 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004135 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004136 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004137 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004138 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004139 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004140 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004141}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004142#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004144
Guido van Rossumb6775db1994-08-01 11:34:53 +00004145#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004146PyDoc_STRVAR(posix_symlink__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004147"symlink(src, dst) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004148Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004149
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004151posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004152{
Mark Hammondef8b6542001-05-13 08:04:26 +00004153 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004154}
4155#endif /* HAVE_SYMLINK */
4156
4157
4158#ifdef HAVE_TIMES
4159#ifndef HZ
4160#define HZ 60 /* Universal constant :-) */
4161#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004162
Guido van Rossumd48f2521997-12-05 22:19:34 +00004163#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4164static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004165system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004166{
4167 ULONG value = 0;
4168
4169 Py_BEGIN_ALLOW_THREADS
4170 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4171 Py_END_ALLOW_THREADS
4172
4173 return value;
4174}
4175
4176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004177posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004178{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004179 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004180 return NULL;
4181
4182 /* Currently Only Uptime is Provided -- Others Later */
4183 return Py_BuildValue("ddddd",
4184 (double)0 /* t.tms_utime / HZ */,
4185 (double)0 /* t.tms_stime / HZ */,
4186 (double)0 /* t.tms_cutime / HZ */,
4187 (double)0 /* t.tms_cstime / HZ */,
4188 (double)system_uptime() / 1000);
4189}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004190#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004192posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004193{
4194 struct tms t;
4195 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004196 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004197 return NULL;
4198 errno = 0;
4199 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004200 if (c == (clock_t) -1)
4201 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004202 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004203 (double)t.tms_utime / HZ,
4204 (double)t.tms_stime / HZ,
4205 (double)t.tms_cutime / HZ,
4206 (double)t.tms_cstime / HZ,
4207 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004208}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004209#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004210#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004211
4212
Guido van Rossum87755a21996-09-07 00:59:43 +00004213#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004214#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004216posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004217{
4218 FILETIME create, exit, kernel, user;
4219 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004220 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004221 return NULL;
4222 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004223 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4224 /* The fields of a FILETIME structure are the hi and lo part
4225 of a 64-bit value expressed in 100 nanosecond units.
4226 1e7 is one second in such units; 1e-7 the inverse.
4227 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4228 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004229 return Py_BuildValue(
4230 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004231 (double)(kernel.dwHighDateTime*429.4967296 +
4232 kernel.dwLowDateTime*1e-7),
4233 (double)(user.dwHighDateTime*429.4967296 +
4234 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004235 (double)0,
4236 (double)0,
4237 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004238}
Guido van Rossum8d665e61996-06-26 18:22:49 +00004239#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004240
4241#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004242PyDoc_STRVAR(posix_times__doc__,
Roger E. Masse0318fd61997-06-05 22:07:58 +00004243"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004244Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004245#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004246
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004247
Guido van Rossumb6775db1994-08-01 11:34:53 +00004248#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004249PyDoc_STRVAR(posix_setsid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004250"setsid() -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004251Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004252
Barry Warsaw53699e91996-12-10 23:23:01 +00004253static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004254posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004255{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004256 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004257 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004258 if (setsid() < 0)
4259 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004260 Py_INCREF(Py_None);
4261 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004262}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004263#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004264
Guido van Rossumb6775db1994-08-01 11:34:53 +00004265#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004266PyDoc_STRVAR(posix_setpgid__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267"setpgid(pid, pgrp) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004268Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004269
Barry Warsaw53699e91996-12-10 23:23:01 +00004270static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004271posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004272{
4273 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004274 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004275 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004276 if (setpgid(pid, pgrp) < 0)
4277 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004278 Py_INCREF(Py_None);
4279 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004280}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004281#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283
Guido van Rossumb6775db1994-08-01 11:34:53 +00004284#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004285PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004286"tcgetpgrp(fd) -> pgid\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004287Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004288
Barry Warsaw53699e91996-12-10 23:23:01 +00004289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004290posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004291{
4292 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004293 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004294 return NULL;
4295 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004296 if (pgid < 0)
4297 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004298 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004299}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004300#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004302
Guido van Rossumb6775db1994-08-01 11:34:53 +00004303#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004304PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004305"tcsetpgrp(fd, pgid) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004306Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004307
Barry Warsaw53699e91996-12-10 23:23:01 +00004308static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004309posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004310{
4311 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004312 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004313 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004314 if (tcsetpgrp(fd, pgid) < 0)
4315 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004316 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004317 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004318}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004319#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004320
Guido van Rossum687dd131993-05-17 08:34:16 +00004321/* Functions acting on file descriptors */
4322
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004323PyDoc_STRVAR(posix_open__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004324"open(filename, flag [, mode=0777]) -> fd\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004325Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004326
Barry Warsaw53699e91996-12-10 23:23:01 +00004327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004328posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004329{
Mark Hammondef8b6542001-05-13 08:04:26 +00004330 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004331 int flag;
4332 int mode = 0777;
4333 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004334 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004335 Py_FileSystemDefaultEncoding, &file,
4336 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004337 return NULL;
4338
Barry Warsaw53699e91996-12-10 23:23:01 +00004339 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004340 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004341 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004342 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004343 return posix_error_with_allocated_filename(file);
4344 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004345 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004346}
4347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004349PyDoc_STRVAR(posix_close__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004350"close(fd) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004351Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004352
Barry Warsaw53699e91996-12-10 23:23:01 +00004353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004354posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004355{
4356 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004357 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004358 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004359 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004360 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004361 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004362 if (res < 0)
4363 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004364 Py_INCREF(Py_None);
4365 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004366}
4367
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004368
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004369PyDoc_STRVAR(posix_dup__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004370"dup(fd) -> fd2\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004371Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004372
Barry Warsaw53699e91996-12-10 23:23:01 +00004373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004374posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004375{
4376 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004377 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004378 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004379 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004380 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004381 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004382 if (fd < 0)
4383 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004384 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004385}
4386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004387
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004388PyDoc_STRVAR(posix_dup2__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004389"dup2(fd, fd2) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004390Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004391
Barry Warsaw53699e91996-12-10 23:23:01 +00004392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004393posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004394{
4395 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004396 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004397 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004398 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004399 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004400 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004401 if (res < 0)
4402 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004403 Py_INCREF(Py_None);
4404 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004405}
4406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004407
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004408PyDoc_STRVAR(posix_lseek__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004409"lseek(fd, pos, how) -> newpos\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004410Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004411
Barry Warsaw53699e91996-12-10 23:23:01 +00004412static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004413posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004414{
4415 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00004416#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004417 LONG_LONG pos, res;
4418#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004419 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004420#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004421 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004422 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004423 return NULL;
4424#ifdef SEEK_SET
4425 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4426 switch (how) {
4427 case 0: how = SEEK_SET; break;
4428 case 1: how = SEEK_CUR; break;
4429 case 2: how = SEEK_END; break;
4430 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004431#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004432
4433#if !defined(HAVE_LARGEFILE_SUPPORT)
4434 pos = PyInt_AsLong(posobj);
4435#else
4436 pos = PyLong_Check(posobj) ?
4437 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4438#endif
4439 if (PyErr_Occurred())
4440 return NULL;
4441
Barry Warsaw53699e91996-12-10 23:23:01 +00004442 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00004443#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004444 res = _lseeki64(fd, pos, how);
4445#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004446 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004447#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004448 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004449 if (res < 0)
4450 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004451
4452#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004453 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004454#else
4455 return PyLong_FromLongLong(res);
4456#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004457}
4458
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004459
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004460PyDoc_STRVAR(posix_read__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004461"read(fd, buffersize) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004462Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004463
Barry Warsaw53699e91996-12-10 23:23:01 +00004464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004465posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004466{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004467 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004468 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004469 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004470 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004471 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004472 if (buffer == NULL)
4473 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004474 Py_BEGIN_ALLOW_THREADS
4475 n = read(fd, PyString_AsString(buffer), size);
4476 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004477 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004478 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004479 return posix_error();
4480 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004481 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004482 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004483 return buffer;
4484}
4485
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004486
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004487PyDoc_STRVAR(posix_write__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004488"write(fd, string) -> byteswritten\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004489Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004490
Barry Warsaw53699e91996-12-10 23:23:01 +00004491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004492posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004493{
4494 int fd, size;
4495 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004496 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004497 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004498 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004499 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004500 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004501 if (size < 0)
4502 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004503 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004504}
4505
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004507PyDoc_STRVAR(posix_fstat__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004508"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004509Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004510
Barry Warsaw53699e91996-12-10 23:23:01 +00004511static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004512posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004513{
4514 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004515 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004516 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004517 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004518 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004519 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004520 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004521 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004522 if (res != 0)
4523 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004524
Fred Drake699f3522000-06-29 21:12:41 +00004525 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004526}
4527
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004529PyDoc_STRVAR(posix_fdopen__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004530"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004531Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004532
Barry Warsaw53699e91996-12-10 23:23:01 +00004533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004534posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004535{
Guido van Rossum687dd131993-05-17 08:34:16 +00004536 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004537 char *mode = "r";
4538 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004539 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004540 PyObject *f;
4541 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004542 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004543
Barry Warsaw53699e91996-12-10 23:23:01 +00004544 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004545 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004546 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004547 if (fp == NULL)
4548 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004549 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004550 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004551 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004552 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004553}
4554
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004555PyDoc_STRVAR(posix_isatty__doc__,
Fred Drake106c1a02002-04-23 15:58:02 +00004556"isatty(fd) -> bool\n\
4557Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004558connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004559
4560static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004561posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004562{
4563 int fd;
4564 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4565 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004566 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004567}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004568
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004569#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004570PyDoc_STRVAR(posix_pipe__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004571"pipe() -> (read_end, write_end)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004572Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004573
Barry Warsaw53699e91996-12-10 23:23:01 +00004574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004575posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004576{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004577#if defined(PYOS_OS2)
4578 HFILE read, write;
4579 APIRET rc;
4580
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004581 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004582 return NULL;
4583
4584 Py_BEGIN_ALLOW_THREADS
4585 rc = DosCreatePipe( &read, &write, 4096);
4586 Py_END_ALLOW_THREADS
4587 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004588 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004589
4590 return Py_BuildValue("(ii)", read, write);
4591#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00004592#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00004593 int fds[2];
4594 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004595 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004596 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004597 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004598 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004599 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004600 if (res != 0)
4601 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004602 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004603#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00004604 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004605 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004606 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004607 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004608 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004609 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004610 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004611 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004612 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004613 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004614 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4615 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004616 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004617#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004618#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004619}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004620#endif /* HAVE_PIPE */
4621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004622
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004623#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004624PyDoc_STRVAR(posix_mkfifo__doc__,
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004625"mkfifo(filename, [, mode=0666]) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004626Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004627
Barry Warsaw53699e91996-12-10 23:23:01 +00004628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004629posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004630{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004631 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004632 int mode = 0666;
4633 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004634 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004635 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004636 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004637 res = mkfifo(filename, mode);
4638 Py_END_ALLOW_THREADS
4639 if (res < 0)
4640 return posix_error();
4641 Py_INCREF(Py_None);
4642 return Py_None;
4643}
4644#endif
4645
4646
4647#ifdef HAVE_MKNOD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004648PyDoc_STRVAR(posix_mknod__doc__,
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004649"mknod(filename, [, mode=0600, major, minor]) -> None\n\
4650Create a filesystem node (file, device special file or named pipe)\n\
4651named filename. mode specifies both the permissions to use and the\n\
4652type of node to be created, being combined (bitwise OR) with one of\n\
4653S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4654major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004655they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004656
4657
4658static PyObject *
4659posix_mknod(PyObject *self, PyObject *args)
4660{
4661 char *filename;
4662 int mode = 0600;
4663 int major = 0;
4664 int minor = 0;
4665 int res;
4666 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4667 &mode, &major, &minor))
4668 return NULL;
4669 Py_BEGIN_ALLOW_THREADS
4670 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004671 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004672 if (res < 0)
4673 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004674 Py_INCREF(Py_None);
4675 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004676}
4677#endif
4678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004679
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004680#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004681PyDoc_STRVAR(posix_ftruncate__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004682"ftruncate(fd, length) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004683Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004684
Barry Warsaw53699e91996-12-10 23:23:01 +00004685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004686posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004687{
4688 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004689 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004690 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004691 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004692
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004693 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004694 return NULL;
4695
4696#if !defined(HAVE_LARGEFILE_SUPPORT)
4697 length = PyInt_AsLong(lenobj);
4698#else
4699 length = PyLong_Check(lenobj) ?
4700 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4701#endif
4702 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004703 return NULL;
4704
Barry Warsaw53699e91996-12-10 23:23:01 +00004705 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004706 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004707 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004708 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004709 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004710 return NULL;
4711 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004712 Py_INCREF(Py_None);
4713 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004714}
4715#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004716
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004717#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004718PyDoc_STRVAR(posix_putenv__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004719"putenv(key, value) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004720Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004721
Fred Drake762e2061999-08-26 17:23:54 +00004722/* Save putenv() parameters as values here, so we can collect them when they
4723 * get re-set with another call for the same key. */
4724static PyObject *posix_putenv_garbage;
4725
Tim Peters5aa91602002-01-30 05:46:57 +00004726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004727posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004728{
4729 char *s1, *s2;
4730 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004731 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004732 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004733
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004734 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004735 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004736
4737#if defined(PYOS_OS2)
4738 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4739 APIRET rc;
4740
4741 if (strlen(s2) == 0) /* If New Value is an Empty String */
4742 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4743
4744 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4745 if (rc != NO_ERROR)
4746 return os2_error(rc);
4747
4748 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4749 APIRET rc;
4750
4751 if (strlen(s2) == 0) /* If New Value is an Empty String */
4752 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4753
4754 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4755 if (rc != NO_ERROR)
4756 return os2_error(rc);
4757 } else {
4758#endif
4759
Fred Drake762e2061999-08-26 17:23:54 +00004760 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004761 len = strlen(s1) + strlen(s2) + 2;
4762 /* len includes space for a trailing \0; the size arg to
4763 PyString_FromStringAndSize does not count that */
4764 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004765 if (newstr == NULL)
4766 return PyErr_NoMemory();
4767 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004768 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004769 if (putenv(new)) {
4770 posix_error();
4771 return NULL;
4772 }
Fred Drake762e2061999-08-26 17:23:54 +00004773 /* Install the first arg and newstr in posix_putenv_garbage;
4774 * this will cause previous value to be collected. This has to
4775 * happen after the real putenv() call because the old value
4776 * was still accessible until then. */
4777 if (PyDict_SetItem(posix_putenv_garbage,
4778 PyTuple_GET_ITEM(args, 0), newstr)) {
4779 /* really not much we can do; just leak */
4780 PyErr_Clear();
4781 }
4782 else {
4783 Py_DECREF(newstr);
4784 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004785
4786#if defined(PYOS_OS2)
4787 }
4788#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004789 Py_INCREF(Py_None);
4790 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004791}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004792#endif /* putenv */
4793
Guido van Rossumc524d952001-10-19 01:31:59 +00004794#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004795PyDoc_STRVAR(posix_unsetenv__doc__,
Guido van Rossumc524d952001-10-19 01:31:59 +00004796"unsetenv(key) -> None\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004797Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00004798
4799static PyObject *
4800posix_unsetenv(PyObject *self, PyObject *args)
4801{
4802 char *s1;
4803
4804 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4805 return NULL;
4806
4807 unsetenv(s1);
4808
4809 /* Remove the key from posix_putenv_garbage;
4810 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004811 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004812 * old value was still accessible until then.
4813 */
4814 if (PyDict_DelItem(posix_putenv_garbage,
4815 PyTuple_GET_ITEM(args, 0))) {
4816 /* really not much we can do; just leak */
4817 PyErr_Clear();
4818 }
4819
4820 Py_INCREF(Py_None);
4821 return Py_None;
4822}
4823#endif /* unsetenv */
4824
Guido van Rossumb6a47161997-09-15 22:54:34 +00004825#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004826PyDoc_STRVAR(posix_strerror__doc__,
Guido van Rossumb6a47161997-09-15 22:54:34 +00004827"strerror(code) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004828Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004829
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004831posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004832{
4833 int code;
4834 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004835 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004836 return NULL;
4837 message = strerror(code);
4838 if (message == NULL) {
4839 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004840 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004841 return NULL;
4842 }
4843 return PyString_FromString(message);
4844}
4845#endif /* strerror */
4846
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004847
Guido van Rossumc9641791998-08-04 15:26:23 +00004848#ifdef HAVE_SYS_WAIT_H
4849
Fred Drake106c1a02002-04-23 15:58:02 +00004850#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004851PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drake106c1a02002-04-23 15:58:02 +00004852"WCOREDUMP(status) -> bool\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004853Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00004854
4855static PyObject *
4856posix_WCOREDUMP(PyObject *self, PyObject *args)
4857{
4858#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;
4866
4867 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4868 {
4869 return NULL;
4870 }
4871
4872 return PyBool_FromLong(WCOREDUMP(status));
4873#undef status_i
4874}
4875#endif /* WCOREDUMP */
4876
4877#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004878PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drake106c1a02002-04-23 15:58:02 +00004879"WIFCONTINUED(status) -> bool\n\
4880Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004881job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00004882
4883static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004884posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004885{
4886#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;
4894
4895 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4896 {
4897 return NULL;
4898 }
4899
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004900 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004901#undef status_i
4902}
4903#endif /* WIFCONTINUED */
4904
Guido van Rossumc9641791998-08-04 15:26:23 +00004905#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004906PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drake106c1a02002-04-23 15:58:02 +00004907"WIFSTOPPED(status) -> bool\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004909
4910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004911posix_WIFSTOPPED(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:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004923 {
4924 return NULL;
4925 }
Tim Peters5aa91602002-01-30 05:46:57 +00004926
Fred Drake106c1a02002-04-23 15:58:02 +00004927 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004928#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004929}
4930#endif /* WIFSTOPPED */
4931
4932#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004933PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drake106c1a02002-04-23 15:58:02 +00004934"WIFSIGNALED(status) -> bool\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004935Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004936
4937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004938posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004939{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004940#ifdef UNION_WAIT
4941 union wait status;
4942#define status_i (status.w_status)
4943#else
4944 int status;
4945#define status_i status
4946#endif
4947 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004948
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004949 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004950 {
4951 return NULL;
4952 }
Tim Peters5aa91602002-01-30 05:46:57 +00004953
Fred Drake106c1a02002-04-23 15:58:02 +00004954 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004955#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004956}
4957#endif /* WIFSIGNALED */
4958
4959#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004960PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drake106c1a02002-04-23 15:58:02 +00004961"WIFEXITED(status) -> bool\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004962Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004963system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004964
4965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004966posix_WIFEXITED(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:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004978 {
4979 return NULL;
4980 }
Tim Peters5aa91602002-01-30 05:46:57 +00004981
Fred Drake106c1a02002-04-23 15:58:02 +00004982 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004983#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004984}
4985#endif /* WIFEXITED */
4986
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004987#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004988PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Guido van Rossumc9641791998-08-04 15:26:23 +00004989"WEXITSTATUS(status) -> integer\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004990Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004991
4992static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004993posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004994{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004995#ifdef UNION_WAIT
4996 union wait status;
4997#define status_i (status.w_status)
4998#else
4999 int status;
5000#define status_i status
5001#endif
5002 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005003
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005004 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005005 {
5006 return NULL;
5007 }
Tim Peters5aa91602002-01-30 05:46:57 +00005008
Guido van Rossumc9641791998-08-04 15:26:23 +00005009 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005010#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005011}
5012#endif /* WEXITSTATUS */
5013
5014#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005015PyDoc_STRVAR(posix_WTERMSIG__doc__,
Guido van Rossumc9641791998-08-04 15:26:23 +00005016"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005017Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005018value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005019
5020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005021posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005022{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005023#ifdef UNION_WAIT
5024 union wait status;
5025#define status_i (status.w_status)
5026#else
5027 int status;
5028#define status_i status
5029#endif
5030 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005031
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005032 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005033 {
5034 return NULL;
5035 }
Tim Peters5aa91602002-01-30 05:46:57 +00005036
Guido van Rossumc9641791998-08-04 15:26:23 +00005037 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005038#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005039}
5040#endif /* WTERMSIG */
5041
5042#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005043PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Guido van Rossumc9641791998-08-04 15:26:23 +00005044"WSTOPSIG(status) -> integer\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005045Return the signal that stopped the process that provided\n\
5046the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005047
5048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005049posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005050{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005051#ifdef UNION_WAIT
5052 union wait status;
5053#define status_i (status.w_status)
5054#else
5055 int status;
5056#define status_i status
5057#endif
5058 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005059
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005060 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005061 {
5062 return NULL;
5063 }
Tim Peters5aa91602002-01-30 05:46:57 +00005064
Guido van Rossumc9641791998-08-04 15:26:23 +00005065 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005066#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005067}
5068#endif /* WSTOPSIG */
5069
5070#endif /* HAVE_SYS_WAIT_H */
5071
5072
Guido van Rossum94f6f721999-01-06 18:42:14 +00005073#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005074#ifdef _SCO_DS
5075/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5076 needed definitions in sys/statvfs.h */
5077#define _SVID3
5078#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005079#include <sys/statvfs.h>
5080
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005081static PyObject*
5082_pystatvfs_fromstructstatvfs(struct statvfs st) {
5083 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5084 if (v == NULL)
5085 return NULL;
5086
5087#if !defined(HAVE_LARGEFILE_SUPPORT)
5088 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5089 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5090 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5091 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5092 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5093 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5094 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5095 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5096 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5097 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5098#else
5099 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5100 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005101 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005102 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005103 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005104 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5105 PyStructSequence_SET_ITEM(v, 4,
5106 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005107 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005108 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005109 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005110 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005111 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005112 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5113 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5114 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5115#endif
5116
5117 return v;
5118}
5119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005120PyDoc_STRVAR(posix_fstatvfs__doc__,
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005121"fstatvfs(fd) -> \n\
5122 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005123Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005124
5125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005126posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005127{
5128 int fd, res;
5129 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005130
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005131 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005132 return NULL;
5133 Py_BEGIN_ALLOW_THREADS
5134 res = fstatvfs(fd, &st);
5135 Py_END_ALLOW_THREADS
5136 if (res != 0)
5137 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005138
5139 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005140}
5141#endif /* HAVE_FSTATVFS */
5142
5143
5144#if defined(HAVE_STATVFS)
5145#include <sys/statvfs.h>
5146
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005147PyDoc_STRVAR(posix_statvfs__doc__,
Guido van Rossum0c9608c1999-02-03 16:32:37 +00005148"statvfs(path) -> \n\
5149 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005150Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005151
5152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005153posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005154{
5155 char *path;
5156 int res;
5157 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005158 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005159 return NULL;
5160 Py_BEGIN_ALLOW_THREADS
5161 res = statvfs(path, &st);
5162 Py_END_ALLOW_THREADS
5163 if (res != 0)
5164 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005165
5166 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005167}
5168#endif /* HAVE_STATVFS */
5169
5170
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005171#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005172PyDoc_STRVAR(posix_tempnam__doc__,
5173"tempnam([dir[, prefix]]) -> string\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005174Return a unique name for a temporary file.\n\
5175The directory and a short may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005176or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005177
5178static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005179posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005180{
5181 PyObject *result = NULL;
5182 char *dir = NULL;
5183 char *pfx = NULL;
5184 char *name;
5185
5186 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5187 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005188
5189 if (PyErr_Warn(PyExc_RuntimeWarning,
5190 "tempnam is a potential security risk to your program") < 0)
5191 return NULL;
5192
Fred Drake78b71c22001-07-17 20:37:36 +00005193#ifdef MS_WIN32
5194 name = _tempnam(dir, pfx);
5195#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005196 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005197#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005198 if (name == NULL)
5199 return PyErr_NoMemory();
5200 result = PyString_FromString(name);
5201 free(name);
5202 return result;
5203}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005204#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005205
5206
5207#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005208PyDoc_STRVAR(posix_tmpfile__doc__,
5209"tmpfile() -> file object\n\
5210Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005211
5212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005213posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005214{
5215 FILE *fp;
5216
5217 if (!PyArg_ParseTuple(args, ":tmpfile"))
5218 return NULL;
5219 fp = tmpfile();
5220 if (fp == NULL)
5221 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005222 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005223}
5224#endif
5225
5226
5227#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005228PyDoc_STRVAR(posix_tmpnam__doc__,
5229"tmpnam() -> string\n\
5230Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005231
5232static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005233posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005234{
5235 char buffer[L_tmpnam];
5236 char *name;
5237
5238 if (!PyArg_ParseTuple(args, ":tmpnam"))
5239 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005240
5241 if (PyErr_Warn(PyExc_RuntimeWarning,
5242 "tmpnam is a potential security risk to your program") < 0)
5243 return NULL;
5244
Greg Wardb48bc172000-03-01 21:51:56 +00005245#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005246 name = tmpnam_r(buffer);
5247#else
5248 name = tmpnam(buffer);
5249#endif
5250 if (name == NULL) {
5251 PyErr_SetObject(PyExc_OSError,
5252 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005253#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005254 "unexpected NULL from tmpnam_r"
5255#else
5256 "unexpected NULL from tmpnam"
5257#endif
5258 ));
5259 return NULL;
5260 }
5261 return PyString_FromString(buffer);
5262}
5263#endif
5264
5265
Fred Drakec9680921999-12-13 16:37:25 +00005266/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5267 * It maps strings representing configuration variable names to
5268 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005269 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005270 * rarely-used constants. There are three separate tables that use
5271 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005272 *
5273 * This code is always included, even if none of the interfaces that
5274 * need it are included. The #if hackery needed to avoid it would be
5275 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005276 */
5277struct constdef {
5278 char *name;
5279 long value;
5280};
5281
Fred Drake12c6e2d1999-12-14 21:25:03 +00005282static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005283conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5284 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005285{
5286 if (PyInt_Check(arg)) {
5287 *valuep = PyInt_AS_LONG(arg);
5288 return 1;
5289 }
5290 if (PyString_Check(arg)) {
5291 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005292 size_t lo = 0;
5293 size_t mid;
5294 size_t hi = tablesize;
5295 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005296 char *confname = PyString_AS_STRING(arg);
5297 while (lo < hi) {
5298 mid = (lo + hi) / 2;
5299 cmp = strcmp(confname, table[mid].name);
5300 if (cmp < 0)
5301 hi = mid;
5302 else if (cmp > 0)
5303 lo = mid + 1;
5304 else {
5305 *valuep = table[mid].value;
5306 return 1;
5307 }
5308 }
5309 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5310 }
5311 else
5312 PyErr_SetString(PyExc_TypeError,
5313 "configuration names must be strings or integers");
5314 return 0;
5315}
5316
5317
5318#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5319static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005320#ifdef _PC_ABI_AIO_XFER_MAX
5321 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5322#endif
5323#ifdef _PC_ABI_ASYNC_IO
5324 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5325#endif
Fred Drakec9680921999-12-13 16:37:25 +00005326#ifdef _PC_ASYNC_IO
5327 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5328#endif
5329#ifdef _PC_CHOWN_RESTRICTED
5330 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5331#endif
5332#ifdef _PC_FILESIZEBITS
5333 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5334#endif
5335#ifdef _PC_LAST
5336 {"PC_LAST", _PC_LAST},
5337#endif
5338#ifdef _PC_LINK_MAX
5339 {"PC_LINK_MAX", _PC_LINK_MAX},
5340#endif
5341#ifdef _PC_MAX_CANON
5342 {"PC_MAX_CANON", _PC_MAX_CANON},
5343#endif
5344#ifdef _PC_MAX_INPUT
5345 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5346#endif
5347#ifdef _PC_NAME_MAX
5348 {"PC_NAME_MAX", _PC_NAME_MAX},
5349#endif
5350#ifdef _PC_NO_TRUNC
5351 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5352#endif
5353#ifdef _PC_PATH_MAX
5354 {"PC_PATH_MAX", _PC_PATH_MAX},
5355#endif
5356#ifdef _PC_PIPE_BUF
5357 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5358#endif
5359#ifdef _PC_PRIO_IO
5360 {"PC_PRIO_IO", _PC_PRIO_IO},
5361#endif
5362#ifdef _PC_SOCK_MAXBUF
5363 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5364#endif
5365#ifdef _PC_SYNC_IO
5366 {"PC_SYNC_IO", _PC_SYNC_IO},
5367#endif
5368#ifdef _PC_VDISABLE
5369 {"PC_VDISABLE", _PC_VDISABLE},
5370#endif
5371};
5372
Fred Drakec9680921999-12-13 16:37:25 +00005373static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005374conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005375{
5376 return conv_confname(arg, valuep, posix_constants_pathconf,
5377 sizeof(posix_constants_pathconf)
5378 / sizeof(struct constdef));
5379}
5380#endif
5381
5382#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005383PyDoc_STRVAR(posix_fpathconf__doc__,
5384"fpathconf(fd, name) -> integer\n\
Fred Drakec9680921999-12-13 16:37:25 +00005385Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005386If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005387
5388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005389posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005390{
5391 PyObject *result = NULL;
5392 int name, fd;
5393
Fred Drake12c6e2d1999-12-14 21:25:03 +00005394 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5395 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005396 long limit;
5397
5398 errno = 0;
5399 limit = fpathconf(fd, name);
5400 if (limit == -1 && errno != 0)
5401 posix_error();
5402 else
5403 result = PyInt_FromLong(limit);
5404 }
5405 return result;
5406}
5407#endif
5408
5409
5410#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005411PyDoc_STRVAR(posix_pathconf__doc__,
5412"pathconf(path, name) -> integer\n\
Fred Drakec9680921999-12-13 16:37:25 +00005413Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005414If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005415
5416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005417posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005418{
5419 PyObject *result = NULL;
5420 int name;
5421 char *path;
5422
5423 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5424 conv_path_confname, &name)) {
5425 long limit;
5426
5427 errno = 0;
5428 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005429 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005430 if (errno == EINVAL)
5431 /* could be a path or name problem */
5432 posix_error();
5433 else
5434 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005435 }
Fred Drakec9680921999-12-13 16:37:25 +00005436 else
5437 result = PyInt_FromLong(limit);
5438 }
5439 return result;
5440}
5441#endif
5442
5443#ifdef HAVE_CONFSTR
5444static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005445#ifdef _CS_ARCHITECTURE
5446 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5447#endif
5448#ifdef _CS_HOSTNAME
5449 {"CS_HOSTNAME", _CS_HOSTNAME},
5450#endif
5451#ifdef _CS_HW_PROVIDER
5452 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5453#endif
5454#ifdef _CS_HW_SERIAL
5455 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5456#endif
5457#ifdef _CS_INITTAB_NAME
5458 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5459#endif
Fred Drakec9680921999-12-13 16:37:25 +00005460#ifdef _CS_LFS64_CFLAGS
5461 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5462#endif
5463#ifdef _CS_LFS64_LDFLAGS
5464 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5465#endif
5466#ifdef _CS_LFS64_LIBS
5467 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5468#endif
5469#ifdef _CS_LFS64_LINTFLAGS
5470 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5471#endif
5472#ifdef _CS_LFS_CFLAGS
5473 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5474#endif
5475#ifdef _CS_LFS_LDFLAGS
5476 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5477#endif
5478#ifdef _CS_LFS_LIBS
5479 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5480#endif
5481#ifdef _CS_LFS_LINTFLAGS
5482 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5483#endif
Fred Draked86ed291999-12-15 15:34:33 +00005484#ifdef _CS_MACHINE
5485 {"CS_MACHINE", _CS_MACHINE},
5486#endif
Fred Drakec9680921999-12-13 16:37:25 +00005487#ifdef _CS_PATH
5488 {"CS_PATH", _CS_PATH},
5489#endif
Fred Draked86ed291999-12-15 15:34:33 +00005490#ifdef _CS_RELEASE
5491 {"CS_RELEASE", _CS_RELEASE},
5492#endif
5493#ifdef _CS_SRPC_DOMAIN
5494 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5495#endif
5496#ifdef _CS_SYSNAME
5497 {"CS_SYSNAME", _CS_SYSNAME},
5498#endif
5499#ifdef _CS_VERSION
5500 {"CS_VERSION", _CS_VERSION},
5501#endif
Fred Drakec9680921999-12-13 16:37:25 +00005502#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5503 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5504#endif
5505#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5506 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5507#endif
5508#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5509 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5510#endif
5511#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5512 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5513#endif
5514#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5515 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5516#endif
5517#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5518 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5519#endif
5520#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5521 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5522#endif
5523#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5524 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5525#endif
5526#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5527 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5528#endif
5529#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5530 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5531#endif
5532#ifdef _CS_XBS5_LP64_OFF64_LIBS
5533 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5534#endif
5535#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5536 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5537#endif
5538#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5539 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5540#endif
5541#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5542 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5543#endif
5544#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5545 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5546#endif
5547#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5548 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5549#endif
Fred Draked86ed291999-12-15 15:34:33 +00005550#ifdef _MIPS_CS_AVAIL_PROCESSORS
5551 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5552#endif
5553#ifdef _MIPS_CS_BASE
5554 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5555#endif
5556#ifdef _MIPS_CS_HOSTID
5557 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5558#endif
5559#ifdef _MIPS_CS_HW_NAME
5560 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5561#endif
5562#ifdef _MIPS_CS_NUM_PROCESSORS
5563 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5564#endif
5565#ifdef _MIPS_CS_OSREL_MAJ
5566 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5567#endif
5568#ifdef _MIPS_CS_OSREL_MIN
5569 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5570#endif
5571#ifdef _MIPS_CS_OSREL_PATCH
5572 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5573#endif
5574#ifdef _MIPS_CS_OS_NAME
5575 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5576#endif
5577#ifdef _MIPS_CS_OS_PROVIDER
5578 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5579#endif
5580#ifdef _MIPS_CS_PROCESSORS
5581 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5582#endif
5583#ifdef _MIPS_CS_SERIAL
5584 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5585#endif
5586#ifdef _MIPS_CS_VENDOR
5587 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5588#endif
Fred Drakec9680921999-12-13 16:37:25 +00005589};
5590
5591static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005592conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005593{
5594 return conv_confname(arg, valuep, posix_constants_confstr,
5595 sizeof(posix_constants_confstr)
5596 / sizeof(struct constdef));
5597}
5598
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005599PyDoc_STRVAR(posix_confstr__doc__,
5600"confstr(name) -> string\n\
5601Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005602
5603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005604posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005605{
5606 PyObject *result = NULL;
5607 int name;
5608 char buffer[64];
5609
5610 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5611 int len = confstr(name, buffer, sizeof(buffer));
5612
Fred Drakec9680921999-12-13 16:37:25 +00005613 errno = 0;
5614 if (len == 0) {
5615 if (errno != 0)
5616 posix_error();
5617 else
5618 result = PyString_FromString("");
5619 }
5620 else {
5621 if (len >= sizeof(buffer)) {
5622 result = PyString_FromStringAndSize(NULL, len);
5623 if (result != NULL)
5624 confstr(name, PyString_AS_STRING(result), len+1);
5625 }
5626 else
5627 result = PyString_FromString(buffer);
5628 }
5629 }
5630 return result;
5631}
5632#endif
5633
5634
5635#ifdef HAVE_SYSCONF
5636static struct constdef posix_constants_sysconf[] = {
5637#ifdef _SC_2_CHAR_TERM
5638 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5639#endif
5640#ifdef _SC_2_C_BIND
5641 {"SC_2_C_BIND", _SC_2_C_BIND},
5642#endif
5643#ifdef _SC_2_C_DEV
5644 {"SC_2_C_DEV", _SC_2_C_DEV},
5645#endif
5646#ifdef _SC_2_C_VERSION
5647 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5648#endif
5649#ifdef _SC_2_FORT_DEV
5650 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5651#endif
5652#ifdef _SC_2_FORT_RUN
5653 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5654#endif
5655#ifdef _SC_2_LOCALEDEF
5656 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5657#endif
5658#ifdef _SC_2_SW_DEV
5659 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5660#endif
5661#ifdef _SC_2_UPE
5662 {"SC_2_UPE", _SC_2_UPE},
5663#endif
5664#ifdef _SC_2_VERSION
5665 {"SC_2_VERSION", _SC_2_VERSION},
5666#endif
Fred Draked86ed291999-12-15 15:34:33 +00005667#ifdef _SC_ABI_ASYNCHRONOUS_IO
5668 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5669#endif
5670#ifdef _SC_ACL
5671 {"SC_ACL", _SC_ACL},
5672#endif
Fred Drakec9680921999-12-13 16:37:25 +00005673#ifdef _SC_AIO_LISTIO_MAX
5674 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5675#endif
Fred Drakec9680921999-12-13 16:37:25 +00005676#ifdef _SC_AIO_MAX
5677 {"SC_AIO_MAX", _SC_AIO_MAX},
5678#endif
5679#ifdef _SC_AIO_PRIO_DELTA_MAX
5680 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5681#endif
5682#ifdef _SC_ARG_MAX
5683 {"SC_ARG_MAX", _SC_ARG_MAX},
5684#endif
5685#ifdef _SC_ASYNCHRONOUS_IO
5686 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5687#endif
5688#ifdef _SC_ATEXIT_MAX
5689 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5690#endif
Fred Draked86ed291999-12-15 15:34:33 +00005691#ifdef _SC_AUDIT
5692 {"SC_AUDIT", _SC_AUDIT},
5693#endif
Fred Drakec9680921999-12-13 16:37:25 +00005694#ifdef _SC_AVPHYS_PAGES
5695 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5696#endif
5697#ifdef _SC_BC_BASE_MAX
5698 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5699#endif
5700#ifdef _SC_BC_DIM_MAX
5701 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5702#endif
5703#ifdef _SC_BC_SCALE_MAX
5704 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5705#endif
5706#ifdef _SC_BC_STRING_MAX
5707 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5708#endif
Fred Draked86ed291999-12-15 15:34:33 +00005709#ifdef _SC_CAP
5710 {"SC_CAP", _SC_CAP},
5711#endif
Fred Drakec9680921999-12-13 16:37:25 +00005712#ifdef _SC_CHARCLASS_NAME_MAX
5713 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5714#endif
5715#ifdef _SC_CHAR_BIT
5716 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5717#endif
5718#ifdef _SC_CHAR_MAX
5719 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5720#endif
5721#ifdef _SC_CHAR_MIN
5722 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5723#endif
5724#ifdef _SC_CHILD_MAX
5725 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5726#endif
5727#ifdef _SC_CLK_TCK
5728 {"SC_CLK_TCK", _SC_CLK_TCK},
5729#endif
5730#ifdef _SC_COHER_BLKSZ
5731 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5732#endif
5733#ifdef _SC_COLL_WEIGHTS_MAX
5734 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5735#endif
5736#ifdef _SC_DCACHE_ASSOC
5737 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5738#endif
5739#ifdef _SC_DCACHE_BLKSZ
5740 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5741#endif
5742#ifdef _SC_DCACHE_LINESZ
5743 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5744#endif
5745#ifdef _SC_DCACHE_SZ
5746 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5747#endif
5748#ifdef _SC_DCACHE_TBLKSZ
5749 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5750#endif
5751#ifdef _SC_DELAYTIMER_MAX
5752 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5753#endif
5754#ifdef _SC_EQUIV_CLASS_MAX
5755 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5756#endif
5757#ifdef _SC_EXPR_NEST_MAX
5758 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5759#endif
5760#ifdef _SC_FSYNC
5761 {"SC_FSYNC", _SC_FSYNC},
5762#endif
5763#ifdef _SC_GETGR_R_SIZE_MAX
5764 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5765#endif
5766#ifdef _SC_GETPW_R_SIZE_MAX
5767 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5768#endif
5769#ifdef _SC_ICACHE_ASSOC
5770 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5771#endif
5772#ifdef _SC_ICACHE_BLKSZ
5773 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5774#endif
5775#ifdef _SC_ICACHE_LINESZ
5776 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5777#endif
5778#ifdef _SC_ICACHE_SZ
5779 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5780#endif
Fred Draked86ed291999-12-15 15:34:33 +00005781#ifdef _SC_INF
5782 {"SC_INF", _SC_INF},
5783#endif
Fred Drakec9680921999-12-13 16:37:25 +00005784#ifdef _SC_INT_MAX
5785 {"SC_INT_MAX", _SC_INT_MAX},
5786#endif
5787#ifdef _SC_INT_MIN
5788 {"SC_INT_MIN", _SC_INT_MIN},
5789#endif
5790#ifdef _SC_IOV_MAX
5791 {"SC_IOV_MAX", _SC_IOV_MAX},
5792#endif
Fred Draked86ed291999-12-15 15:34:33 +00005793#ifdef _SC_IP_SECOPTS
5794 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5795#endif
Fred Drakec9680921999-12-13 16:37:25 +00005796#ifdef _SC_JOB_CONTROL
5797 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5798#endif
Fred Draked86ed291999-12-15 15:34:33 +00005799#ifdef _SC_KERN_POINTERS
5800 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5801#endif
5802#ifdef _SC_KERN_SIM
5803 {"SC_KERN_SIM", _SC_KERN_SIM},
5804#endif
Fred Drakec9680921999-12-13 16:37:25 +00005805#ifdef _SC_LINE_MAX
5806 {"SC_LINE_MAX", _SC_LINE_MAX},
5807#endif
5808#ifdef _SC_LOGIN_NAME_MAX
5809 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5810#endif
5811#ifdef _SC_LOGNAME_MAX
5812 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5813#endif
5814#ifdef _SC_LONG_BIT
5815 {"SC_LONG_BIT", _SC_LONG_BIT},
5816#endif
Fred Draked86ed291999-12-15 15:34:33 +00005817#ifdef _SC_MAC
5818 {"SC_MAC", _SC_MAC},
5819#endif
Fred Drakec9680921999-12-13 16:37:25 +00005820#ifdef _SC_MAPPED_FILES
5821 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5822#endif
5823#ifdef _SC_MAXPID
5824 {"SC_MAXPID", _SC_MAXPID},
5825#endif
5826#ifdef _SC_MB_LEN_MAX
5827 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5828#endif
5829#ifdef _SC_MEMLOCK
5830 {"SC_MEMLOCK", _SC_MEMLOCK},
5831#endif
5832#ifdef _SC_MEMLOCK_RANGE
5833 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5834#endif
5835#ifdef _SC_MEMORY_PROTECTION
5836 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5837#endif
5838#ifdef _SC_MESSAGE_PASSING
5839 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5840#endif
Fred Draked86ed291999-12-15 15:34:33 +00005841#ifdef _SC_MMAP_FIXED_ALIGNMENT
5842 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5843#endif
Fred Drakec9680921999-12-13 16:37:25 +00005844#ifdef _SC_MQ_OPEN_MAX
5845 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5846#endif
5847#ifdef _SC_MQ_PRIO_MAX
5848 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5849#endif
Fred Draked86ed291999-12-15 15:34:33 +00005850#ifdef _SC_NACLS_MAX
5851 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5852#endif
Fred Drakec9680921999-12-13 16:37:25 +00005853#ifdef _SC_NGROUPS_MAX
5854 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5855#endif
5856#ifdef _SC_NL_ARGMAX
5857 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5858#endif
5859#ifdef _SC_NL_LANGMAX
5860 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5861#endif
5862#ifdef _SC_NL_MSGMAX
5863 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5864#endif
5865#ifdef _SC_NL_NMAX
5866 {"SC_NL_NMAX", _SC_NL_NMAX},
5867#endif
5868#ifdef _SC_NL_SETMAX
5869 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5870#endif
5871#ifdef _SC_NL_TEXTMAX
5872 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5873#endif
5874#ifdef _SC_NPROCESSORS_CONF
5875 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5876#endif
5877#ifdef _SC_NPROCESSORS_ONLN
5878 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5879#endif
Fred Draked86ed291999-12-15 15:34:33 +00005880#ifdef _SC_NPROC_CONF
5881 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5882#endif
5883#ifdef _SC_NPROC_ONLN
5884 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5885#endif
Fred Drakec9680921999-12-13 16:37:25 +00005886#ifdef _SC_NZERO
5887 {"SC_NZERO", _SC_NZERO},
5888#endif
5889#ifdef _SC_OPEN_MAX
5890 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5891#endif
5892#ifdef _SC_PAGESIZE
5893 {"SC_PAGESIZE", _SC_PAGESIZE},
5894#endif
5895#ifdef _SC_PAGE_SIZE
5896 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5897#endif
5898#ifdef _SC_PASS_MAX
5899 {"SC_PASS_MAX", _SC_PASS_MAX},
5900#endif
5901#ifdef _SC_PHYS_PAGES
5902 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5903#endif
5904#ifdef _SC_PII
5905 {"SC_PII", _SC_PII},
5906#endif
5907#ifdef _SC_PII_INTERNET
5908 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5909#endif
5910#ifdef _SC_PII_INTERNET_DGRAM
5911 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5912#endif
5913#ifdef _SC_PII_INTERNET_STREAM
5914 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5915#endif
5916#ifdef _SC_PII_OSI
5917 {"SC_PII_OSI", _SC_PII_OSI},
5918#endif
5919#ifdef _SC_PII_OSI_CLTS
5920 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5921#endif
5922#ifdef _SC_PII_OSI_COTS
5923 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5924#endif
5925#ifdef _SC_PII_OSI_M
5926 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5927#endif
5928#ifdef _SC_PII_SOCKET
5929 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5930#endif
5931#ifdef _SC_PII_XTI
5932 {"SC_PII_XTI", _SC_PII_XTI},
5933#endif
5934#ifdef _SC_POLL
5935 {"SC_POLL", _SC_POLL},
5936#endif
5937#ifdef _SC_PRIORITIZED_IO
5938 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5939#endif
5940#ifdef _SC_PRIORITY_SCHEDULING
5941 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5942#endif
5943#ifdef _SC_REALTIME_SIGNALS
5944 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5945#endif
5946#ifdef _SC_RE_DUP_MAX
5947 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5948#endif
5949#ifdef _SC_RTSIG_MAX
5950 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5951#endif
5952#ifdef _SC_SAVED_IDS
5953 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5954#endif
5955#ifdef _SC_SCHAR_MAX
5956 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5957#endif
5958#ifdef _SC_SCHAR_MIN
5959 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5960#endif
5961#ifdef _SC_SELECT
5962 {"SC_SELECT", _SC_SELECT},
5963#endif
5964#ifdef _SC_SEMAPHORES
5965 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5966#endif
5967#ifdef _SC_SEM_NSEMS_MAX
5968 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5969#endif
5970#ifdef _SC_SEM_VALUE_MAX
5971 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5972#endif
5973#ifdef _SC_SHARED_MEMORY_OBJECTS
5974 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5975#endif
5976#ifdef _SC_SHRT_MAX
5977 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5978#endif
5979#ifdef _SC_SHRT_MIN
5980 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5981#endif
5982#ifdef _SC_SIGQUEUE_MAX
5983 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5984#endif
5985#ifdef _SC_SIGRT_MAX
5986 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5987#endif
5988#ifdef _SC_SIGRT_MIN
5989 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5990#endif
Fred Draked86ed291999-12-15 15:34:33 +00005991#ifdef _SC_SOFTPOWER
5992 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5993#endif
Fred Drakec9680921999-12-13 16:37:25 +00005994#ifdef _SC_SPLIT_CACHE
5995 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5996#endif
5997#ifdef _SC_SSIZE_MAX
5998 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5999#endif
6000#ifdef _SC_STACK_PROT
6001 {"SC_STACK_PROT", _SC_STACK_PROT},
6002#endif
6003#ifdef _SC_STREAM_MAX
6004 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6005#endif
6006#ifdef _SC_SYNCHRONIZED_IO
6007 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6008#endif
6009#ifdef _SC_THREADS
6010 {"SC_THREADS", _SC_THREADS},
6011#endif
6012#ifdef _SC_THREAD_ATTR_STACKADDR
6013 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6014#endif
6015#ifdef _SC_THREAD_ATTR_STACKSIZE
6016 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6017#endif
6018#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6019 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6020#endif
6021#ifdef _SC_THREAD_KEYS_MAX
6022 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6023#endif
6024#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6025 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6026#endif
6027#ifdef _SC_THREAD_PRIO_INHERIT
6028 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6029#endif
6030#ifdef _SC_THREAD_PRIO_PROTECT
6031 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6032#endif
6033#ifdef _SC_THREAD_PROCESS_SHARED
6034 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6035#endif
6036#ifdef _SC_THREAD_SAFE_FUNCTIONS
6037 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6038#endif
6039#ifdef _SC_THREAD_STACK_MIN
6040 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6041#endif
6042#ifdef _SC_THREAD_THREADS_MAX
6043 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6044#endif
6045#ifdef _SC_TIMERS
6046 {"SC_TIMERS", _SC_TIMERS},
6047#endif
6048#ifdef _SC_TIMER_MAX
6049 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6050#endif
6051#ifdef _SC_TTY_NAME_MAX
6052 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6053#endif
6054#ifdef _SC_TZNAME_MAX
6055 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6056#endif
6057#ifdef _SC_T_IOV_MAX
6058 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6059#endif
6060#ifdef _SC_UCHAR_MAX
6061 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6062#endif
6063#ifdef _SC_UINT_MAX
6064 {"SC_UINT_MAX", _SC_UINT_MAX},
6065#endif
6066#ifdef _SC_UIO_MAXIOV
6067 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6068#endif
6069#ifdef _SC_ULONG_MAX
6070 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6071#endif
6072#ifdef _SC_USHRT_MAX
6073 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6074#endif
6075#ifdef _SC_VERSION
6076 {"SC_VERSION", _SC_VERSION},
6077#endif
6078#ifdef _SC_WORD_BIT
6079 {"SC_WORD_BIT", _SC_WORD_BIT},
6080#endif
6081#ifdef _SC_XBS5_ILP32_OFF32
6082 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6083#endif
6084#ifdef _SC_XBS5_ILP32_OFFBIG
6085 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6086#endif
6087#ifdef _SC_XBS5_LP64_OFF64
6088 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6089#endif
6090#ifdef _SC_XBS5_LPBIG_OFFBIG
6091 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6092#endif
6093#ifdef _SC_XOPEN_CRYPT
6094 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6095#endif
6096#ifdef _SC_XOPEN_ENH_I18N
6097 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6098#endif
6099#ifdef _SC_XOPEN_LEGACY
6100 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6101#endif
6102#ifdef _SC_XOPEN_REALTIME
6103 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6104#endif
6105#ifdef _SC_XOPEN_REALTIME_THREADS
6106 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6107#endif
6108#ifdef _SC_XOPEN_SHM
6109 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6110#endif
6111#ifdef _SC_XOPEN_UNIX
6112 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6113#endif
6114#ifdef _SC_XOPEN_VERSION
6115 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6116#endif
6117#ifdef _SC_XOPEN_XCU_VERSION
6118 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6119#endif
6120#ifdef _SC_XOPEN_XPG2
6121 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6122#endif
6123#ifdef _SC_XOPEN_XPG3
6124 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6125#endif
6126#ifdef _SC_XOPEN_XPG4
6127 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6128#endif
6129};
6130
6131static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006132conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006133{
6134 return conv_confname(arg, valuep, posix_constants_sysconf,
6135 sizeof(posix_constants_sysconf)
6136 / sizeof(struct constdef));
6137}
6138
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006139PyDoc_STRVAR(posix_sysconf__doc__,
6140"sysconf(name) -> integer\n\
6141Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006142
6143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006144posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006145{
6146 PyObject *result = NULL;
6147 int name;
6148
6149 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6150 int value;
6151
6152 errno = 0;
6153 value = sysconf(name);
6154 if (value == -1 && errno != 0)
6155 posix_error();
6156 else
6157 result = PyInt_FromLong(value);
6158 }
6159 return result;
6160}
6161#endif
6162
6163
Fred Drakebec628d1999-12-15 18:31:10 +00006164/* This code is used to ensure that the tables of configuration value names
6165 * are in sorted order as required by conv_confname(), and also to build the
6166 * the exported dictionaries that are used to publish information about the
6167 * names available on the host platform.
6168 *
6169 * Sorting the table at runtime ensures that the table is properly ordered
6170 * when used, even for platforms we're not able to test on. It also makes
6171 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006172 */
Fred Drakebec628d1999-12-15 18:31:10 +00006173
6174static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006175cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006176{
6177 const struct constdef *c1 =
6178 (const struct constdef *) v1;
6179 const struct constdef *c2 =
6180 (const struct constdef *) v2;
6181
6182 return strcmp(c1->name, c2->name);
6183}
6184
6185static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006186setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006187 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006188{
Fred Drakebec628d1999-12-15 18:31:10 +00006189 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006190 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006191
6192 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6193 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006194 if (d == NULL)
6195 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006196
Barry Warsaw3155db32000-04-13 15:20:40 +00006197 for (i=0; i < tablesize; ++i) {
6198 PyObject *o = PyInt_FromLong(table[i].value);
6199 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6200 Py_XDECREF(o);
6201 Py_DECREF(d);
6202 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006203 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006204 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006205 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006206 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006207}
6208
Fred Drakebec628d1999-12-15 18:31:10 +00006209/* Return -1 on failure, 0 on success. */
6210static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006211setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006212{
6213#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006214 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006215 sizeof(posix_constants_pathconf)
6216 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006217 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006218 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006219#endif
6220#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006221 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006222 sizeof(posix_constants_confstr)
6223 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006224 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006225 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006226#endif
6227#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006228 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006229 sizeof(posix_constants_sysconf)
6230 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006231 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006232 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006233#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006234 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006235}
Fred Draked86ed291999-12-15 15:34:33 +00006236
6237
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006238PyDoc_STRVAR(posix_abort__doc__,
6239"abort() -> does not return!\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006240Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006241in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006242
6243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006244posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006245{
6246 if (!PyArg_ParseTuple(args, ":abort"))
6247 return NULL;
6248 abort();
6249 /*NOTREACHED*/
6250 Py_FatalError("abort() called from Python code didn't abort!");
6251 return NULL;
6252}
Fred Drakebec628d1999-12-15 18:31:10 +00006253
Tim Petersf58a7aa2000-09-22 10:05:54 +00006254#ifdef MS_WIN32
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006255PyDoc_STRVAR(win32_startfile__doc__,
6256"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006257\n\
6258This acts like double-clicking the file in Explorer, or giving the file\n\
6259name as an argument to the DOS \"start\" command: the file is opened\n\
6260with whatever application (if any) its extension is associated.\n\
6261\n\
6262startfile returns as soon as the associated application is launched.\n\
6263There is no option to wait for the application to close, and no way\n\
6264to retrieve the application's exit status.\n\
6265\n\
6266The filepath is relative to the current directory. If you want to use\n\
6267an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006268the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006269
6270static PyObject *
6271win32_startfile(PyObject *self, PyObject *args)
6272{
6273 char *filepath;
6274 HINSTANCE rc;
6275 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6276 return NULL;
6277 Py_BEGIN_ALLOW_THREADS
6278 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6279 Py_END_ALLOW_THREADS
6280 if (rc <= (HINSTANCE)32)
6281 return win32_error("startfile", filepath);
6282 Py_INCREF(Py_None);
6283 return Py_None;
6284}
6285#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006286
6287static PyMethodDef posix_methods[] = {
6288 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6289#ifdef HAVE_TTYNAME
6290 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6291#endif
6292 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6293 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006294#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006295 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006296#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006297#ifdef HAVE_CHROOT
6298 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6299#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006300#ifdef HAVE_CTERMID
6301 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6302#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006303#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006304 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006305#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006306#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006307 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006308#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006309 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6310 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6311 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006312#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006313 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006314#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006315#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006316 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006317#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006318 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6319 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6320 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006321#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006322 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006323#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006324#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006325 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006326#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006327 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006328#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006329 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006330#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006331 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6332 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6333 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006334#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006335 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006336#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006337 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006338#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006339 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6340 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006341#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006342#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006343 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6344 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006345#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006346#ifdef HAVE_FORK1
6347 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6348#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006349#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006350 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006351#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006352#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006353 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006354#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006355#ifdef HAVE_FORKPTY
6356 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6357#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006358#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006359 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006360#endif /* HAVE_GETEGID */
6361#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006362 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006363#endif /* HAVE_GETEUID */
6364#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006366#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006367#ifdef HAVE_GETGROUPS
6368 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6369#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006370 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006371#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006372 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006373#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006374#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006375 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006376#endif /* HAVE_GETPPID */
6377#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006378 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006379#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006380#ifdef HAVE_GETLOGIN
6381 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6382#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006383#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006384 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006385#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006386#ifdef HAVE_KILLPG
6387 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6388#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006389#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006390 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006391#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006392#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006393 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006394#ifdef MS_WIN32
6395 {"popen2", win32_popen2, METH_VARARGS},
6396 {"popen3", win32_popen3, METH_VARARGS},
6397 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006398 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006399#else
6400#if defined(PYOS_OS2) && defined(PYCC_GCC)
6401 {"popen2", os2emx_popen2, METH_VARARGS},
6402 {"popen3", os2emx_popen3, METH_VARARGS},
6403 {"popen4", os2emx_popen4, METH_VARARGS},
6404#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006405#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006406#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006407#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006408 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006409#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006410#ifdef HAVE_SETEUID
6411 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6412#endif /* HAVE_SETEUID */
6413#ifdef HAVE_SETEGID
6414 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6415#endif /* HAVE_SETEGID */
6416#ifdef HAVE_SETREUID
6417 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6418#endif /* HAVE_SETREUID */
6419#ifdef HAVE_SETREGID
6420 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6421#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006422#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006423 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006424#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006425#ifdef HAVE_SETGROUPS
6426 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6427#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006428#ifdef HAVE_GETPGID
6429 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6430#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006431#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006432 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006433#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006434#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006435 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006436#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006437#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006438 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006439#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006440#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006441 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006442#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006443#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006444 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006445#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006446#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006447 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006448#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006449#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006450 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006451#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006452 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6453 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6454 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6455 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6456 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6457 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6458 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6459 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6460 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006461 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006462#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006463 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006464#endif
6465#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006466 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006467#endif
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006468#ifdef HAVE_MKNOD
6469 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6470#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006471#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006472 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006473#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006474#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006475 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006476#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006477#ifdef HAVE_UNSETENV
6478 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6479#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006480#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006481 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006482#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006483#ifdef HAVE_FCHDIR
6484 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6485#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006486#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006487 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006488#endif
6489#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006490 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006491#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006492#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006493#ifdef WCOREDUMP
6494 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6495#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006496#ifdef WIFCONTINUED
6497 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6498#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006499#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006500 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006501#endif /* WIFSTOPPED */
6502#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006503 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006504#endif /* WIFSIGNALED */
6505#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006506 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006507#endif /* WIFEXITED */
6508#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006509 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006510#endif /* WEXITSTATUS */
6511#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006512 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006513#endif /* WTERMSIG */
6514#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006515 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006516#endif /* WSTOPSIG */
6517#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006518#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006519 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006520#endif
6521#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006522 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006523#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006524#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006525 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6526#endif
6527#ifdef HAVE_TEMPNAM
6528 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6529#endif
6530#ifdef HAVE_TMPNAM
6531 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6532#endif
Fred Drakec9680921999-12-13 16:37:25 +00006533#ifdef HAVE_CONFSTR
6534 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6535#endif
6536#ifdef HAVE_SYSCONF
6537 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6538#endif
6539#ifdef HAVE_FPATHCONF
6540 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6541#endif
6542#ifdef HAVE_PATHCONF
6543 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6544#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006545 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00006546#ifdef MS_WIN32
6547 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6548#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006549 {NULL, NULL} /* Sentinel */
6550};
6551
6552
Barry Warsaw4a342091996-12-19 23:50:02 +00006553static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006554ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006555{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006556 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006557}
6558
Guido van Rossumd48f2521997-12-05 22:19:34 +00006559#if defined(PYOS_OS2)
6560/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006561static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006562{
6563 APIRET rc;
6564 ULONG values[QSV_MAX+1];
6565 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006566 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006567
6568 Py_BEGIN_ALLOW_THREADS
6569 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6570 Py_END_ALLOW_THREADS
6571
6572 if (rc != NO_ERROR) {
6573 os2_error(rc);
6574 return -1;
6575 }
6576
Fred Drake4d1e64b2002-04-15 19:40:07 +00006577 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6578 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6579 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6580 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6581 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6582 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6583 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006584
6585 switch (values[QSV_VERSION_MINOR]) {
6586 case 0: ver = "2.00"; break;
6587 case 10: ver = "2.10"; break;
6588 case 11: ver = "2.11"; break;
6589 case 30: ver = "3.00"; break;
6590 case 40: ver = "4.00"; break;
6591 case 50: ver = "5.00"; break;
6592 default:
Tim Peters885d4572001-11-28 20:27:42 +00006593 PyOS_snprintf(tmp, sizeof(tmp),
6594 "%d-%d", values[QSV_VERSION_MAJOR],
6595 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006596 ver = &tmp[0];
6597 }
6598
6599 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006600 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006601 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006602
6603 /* Add Indicator of Which Drive was Used to Boot the System */
6604 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6605 tmp[1] = ':';
6606 tmp[2] = '\0';
6607
Fred Drake4d1e64b2002-04-15 19:40:07 +00006608 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006609}
6610#endif
6611
Barry Warsaw4a342091996-12-19 23:50:02 +00006612static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006613all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006614{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006615#ifdef F_OK
6616 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006617#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006618#ifdef R_OK
6619 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006620#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006621#ifdef W_OK
6622 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006623#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006624#ifdef X_OK
6625 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006626#endif
Fred Drakec9680921999-12-13 16:37:25 +00006627#ifdef NGROUPS_MAX
6628 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6629#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006630#ifdef TMP_MAX
6631 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6632#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006633#ifdef WCONTINUED
6634 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6635#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006636#ifdef WNOHANG
6637 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006638#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006639#ifdef WUNTRACED
6640 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6641#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006642#ifdef O_RDONLY
6643 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6644#endif
6645#ifdef O_WRONLY
6646 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6647#endif
6648#ifdef O_RDWR
6649 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6650#endif
6651#ifdef O_NDELAY
6652 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6653#endif
6654#ifdef O_NONBLOCK
6655 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6656#endif
6657#ifdef O_APPEND
6658 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6659#endif
6660#ifdef O_DSYNC
6661 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6662#endif
6663#ifdef O_RSYNC
6664 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6665#endif
6666#ifdef O_SYNC
6667 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6668#endif
6669#ifdef O_NOCTTY
6670 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6671#endif
6672#ifdef O_CREAT
6673 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6674#endif
6675#ifdef O_EXCL
6676 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6677#endif
6678#ifdef O_TRUNC
6679 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6680#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006681#ifdef O_BINARY
6682 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6683#endif
6684#ifdef O_TEXT
6685 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6686#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006687#ifdef O_LARGEFILE
6688 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6689#endif
6690
Tim Peters5aa91602002-01-30 05:46:57 +00006691/* MS Windows */
6692#ifdef O_NOINHERIT
6693 /* Don't inherit in child processes. */
6694 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6695#endif
6696#ifdef _O_SHORT_LIVED
6697 /* Optimize for short life (keep in memory). */
6698 /* MS forgot to define this one with a non-underscore form too. */
6699 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6700#endif
6701#ifdef O_TEMPORARY
6702 /* Automatically delete when last handle is closed. */
6703 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6704#endif
6705#ifdef O_RANDOM
6706 /* Optimize for random access. */
6707 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6708#endif
6709#ifdef O_SEQUENTIAL
6710 /* Optimize for sequential access. */
6711 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6712#endif
6713
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006714/* GNU extensions. */
6715#ifdef O_DIRECT
6716 /* Direct disk access. */
6717 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6718#endif
6719#ifdef O_DIRECTORY
6720 /* Must be a directory. */
6721 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6722#endif
6723#ifdef O_NOFOLLOW
6724 /* Do not follow links. */
6725 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6726#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006727
Guido van Rossum246bc171999-02-01 23:54:31 +00006728#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006729#if defined(PYOS_OS2) && defined(PYCC_GCC)
6730 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6731 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6732 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6733 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6734 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6735 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6736 if (ins(d, "P_PM", (long)P_PM)) return -1;
6737 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6738 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6739 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6740 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6741 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6742 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6743 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6744 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6745 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6746 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6747 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6748 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6749 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6750#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006751 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6752 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6753 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6754 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6755 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006756#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006757#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006758
Guido van Rossumd48f2521997-12-05 22:19:34 +00006759#if defined(PYOS_OS2)
6760 if (insertvalues(d)) return -1;
6761#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006762 return 0;
6763}
6764
6765
Tim Peters5aa91602002-01-30 05:46:57 +00006766#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006767#define INITFUNC initnt
6768#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006769
6770#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006771#define INITFUNC initos2
6772#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006773
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006774#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006775#define INITFUNC initposix
6776#define MODNAME "posix"
6777#endif
6778
Guido van Rossum3886bb61998-12-04 18:50:17 +00006779DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006780INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006781{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006782 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006783
Fred Drake4d1e64b2002-04-15 19:40:07 +00006784 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006785 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006786 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006787
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006788 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006789 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006790 Py_XINCREF(v);
6791 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006792 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006793 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006794
Fred Drake4d1e64b2002-04-15 19:40:07 +00006795 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006796 return;
6797
Fred Drake4d1e64b2002-04-15 19:40:07 +00006798 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006799 return;
6800
Fred Drake4d1e64b2002-04-15 19:40:07 +00006801 Py_INCREF(PyExc_OSError);
6802 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006803
Guido van Rossumb3d39562000-01-31 18:41:26 +00006804#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006805 if (posix_putenv_garbage == NULL)
6806 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006807#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006808
Guido van Rossum14648392001-12-08 18:02:58 +00006809 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006810 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006811 Py_INCREF((PyObject*) &StatResultType);
6812 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006813
Guido van Rossum14648392001-12-08 18:02:58 +00006814 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006815 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006816 Py_INCREF((PyObject*) &StatVFSResultType);
6817 PyModule_AddObject(m, "statvfs_result",
6818 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006819}