blob: 47bea6f9f92d85ce37b9e5d3089194975ce4f220 [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
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' 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
Guido van Rossuma1065681999-01-25 23:20:23 +000085#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000086#define HAVE_EXECV 1
87#define HAVE_PIPE 1
88#define HAVE_POPEN 1
89#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000090#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000091#else
92#if defined(PYOS_OS2) && defined(PYCC_GCC)
93/* Everything needed is defined in PC/os2emx/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#else /* all other compilers */
95/* Unix functions that the configure script doesn't check for */
96#define HAVE_EXECV 1
97#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000098#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
99#define HAVE_FORK1 1
100#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_GETCWD 1
102#define HAVE_GETEGID 1
103#define HAVE_GETEUID 1
104#define HAVE_GETGID 1
105#define HAVE_GETPPID 1
106#define HAVE_GETUID 1
107#define HAVE_KILL 1
108#define HAVE_OPENDIR 1
109#define HAVE_PIPE 1
110#define HAVE_POPEN 1
111#define HAVE_SYSTEM 1
112#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000113#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000114#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#endif /* _MSC_VER */
116#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000117#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000118#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000119
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000121
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000122#if defined(sun) && !defined(__SVR4)
123/* SunOS 4.1.4 doesn't have prototypes for these: */
124extern int rename(const char *, const char *);
125extern int pclose(FILE *);
126extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000127extern int fsync(int);
128extern int lstat(const char *, struct stat *);
129extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000130#endif
131
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000132#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000135#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000136#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000138#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000139extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#endif
142#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int chdir(char *);
144extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000145#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(const char *);
147extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000149#ifdef __BORLANDC__
150extern int chmod(const char *, int);
151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000153#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int chown(const char *, uid_t, gid_t);
155extern char *getcwd(char *, int);
156extern char *strerror(int);
157extern int link(const char *, const char *);
158extern int rename(const char *, const char *);
159extern int stat(const char *, struct stat *);
160extern int unlink(const char *);
161extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000164#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000167#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000169
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172#ifdef HAVE_UTIME_H
173#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000174#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000176#ifdef HAVE_SYS_UTIME_H
177#include <sys/utime.h>
178#define HAVE_UTIME_H /* pretend we do for the rest of this file */
179#endif /* HAVE_SYS_UTIME_H */
180
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181#ifdef HAVE_SYS_TIMES_H
182#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000183#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184
185#ifdef HAVE_SYS_PARAM_H
186#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000187#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000188
189#ifdef HAVE_SYS_UTSNAME_H
190#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000191#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000193#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000195#define NAMLEN(dirent) strlen((dirent)->d_name)
196#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000197#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#include <direct.h>
199#define NAMLEN(dirent) strlen((dirent)->d_name)
200#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000202#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#endif
207#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#include <direct.h>
217#include <io.h>
218#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000219#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000220#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000222#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000224#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossumd48f2521997-12-05 22:19:34 +0000227#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230
Tim Petersbc2e10e2002-03-03 23:17:02 +0000231#ifndef MAXPATHLEN
232#define MAXPATHLEN 1024
233#endif /* MAXPATHLEN */
234
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000235#ifdef UNION_WAIT
236/* Emulate some macros on systems that have a union instead of macros */
237
238#ifndef WIFEXITED
239#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
240#endif
241
242#ifndef WEXITSTATUS
243#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
244#endif
245
246#ifndef WTERMSIG
247#define WTERMSIG(u_wait) ((u_wait).w_termsig)
248#endif
249
250#endif /* UNION_WAIT */
251
Greg Wardb48bc172000-03-01 21:51:56 +0000252/* Don't use the "_r" form if we don't need it (also, won't have a
253 prototype for it, at least on Solaris -- maybe others as well?). */
254#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
255#define USE_CTERMID_R
256#endif
257
258#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
259#define USE_TMPNAM_R
260#endif
261
Fred Drake699f3522000-06-29 21:12:41 +0000262/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000263#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000264#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000265# define STAT _stati64
266# define FSTAT _fstati64
267# define STRUCT_STAT struct _stati64
268#else
269# define STAT stat
270# define FSTAT fstat
271# define STRUCT_STAT struct stat
272#endif
273
Neal Norwitz3d949422002-04-20 13:46:43 +0000274#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
275#include <sys/mkdev.h>
276#endif
Fred Drake699f3522000-06-29 21:12:41 +0000277
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278/* Return a dictionary corresponding to the POSIX environment table */
279
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000280#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283
Barry Warsaw53699e91996-12-10 23:23:01 +0000284static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000285convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286{
Barry Warsaw53699e91996-12-10 23:23:01 +0000287 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000289 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 if (d == NULL)
291 return NULL;
292 if (environ == NULL)
293 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000294 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000296 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000297 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298 char *p = strchr(*e, '=');
299 if (p == NULL)
300 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000301 k = PyString_FromStringAndSize(*e, (int)(p-*e));
302 if (k == NULL) {
303 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000305 }
306 v = PyString_FromString(p+1);
307 if (v == NULL) {
308 PyErr_Clear();
309 Py_DECREF(k);
310 continue;
311 }
312 if (PyDict_GetItem(d, k) == NULL) {
313 if (PyDict_SetItem(d, k, v) != 0)
314 PyErr_Clear();
315 }
316 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000317 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000319#if defined(PYOS_OS2)
320 {
321 APIRET rc;
322 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
323
324 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000325 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000326 PyObject *v = PyString_FromString(buffer);
327 PyDict_SetItemString(d, "BEGINLIBPATH", v);
328 Py_DECREF(v);
329 }
330 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
331 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
332 PyObject *v = PyString_FromString(buffer);
333 PyDict_SetItemString(d, "ENDLIBPATH", v);
334 Py_DECREF(v);
335 }
336 }
337#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338 return d;
339}
340
341
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342/* Set a POSIX-specific error from errno, and return NULL */
343
Barry Warsawd58d7641998-07-23 16:14:40 +0000344static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000345posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000346{
Barry Warsawca74da41999-02-09 19:31:45 +0000347 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348}
Barry Warsawd58d7641998-07-23 16:14:40 +0000349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000350posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000351{
Barry Warsawca74da41999-02-09 19:31:45 +0000352 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000353}
354
Mark Hammondef8b6542001-05-13 08:04:26 +0000355static PyObject *
356posix_error_with_allocated_filename(char* name)
357{
358 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
359 PyMem_Free(name);
360 return rc;
361}
362
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000363#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000364static PyObject *
365win32_error(char* function, char* filename)
366{
Mark Hammond33a6da92000-08-15 00:46:38 +0000367 /* XXX We should pass the function name along in the future.
368 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000369 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000370 Windows error object, which is non-trivial.
371 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000372 errno = GetLastError();
373 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000374 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000375 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000376 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000377}
378#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379
Guido van Rossumd48f2521997-12-05 22:19:34 +0000380#if defined(PYOS_OS2)
381/**********************************************************************
382 * Helper Function to Trim and Format OS/2 Messages
383 **********************************************************************/
384 static void
385os2_formatmsg(char *msgbuf, int msglen, char *reason)
386{
387 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
388
389 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
390 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
391
392 while (lastc > msgbuf && isspace(*lastc))
393 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
394 }
395
396 /* Add Optional Reason Text */
397 if (reason) {
398 strcat(msgbuf, " : ");
399 strcat(msgbuf, reason);
400 }
401}
402
403/**********************************************************************
404 * Decode an OS/2 Operating System Error Code
405 *
406 * A convenience function to lookup an OS/2 error code and return a
407 * text message we can use to raise a Python exception.
408 *
409 * Notes:
410 * The messages for errors returned from the OS/2 kernel reside in
411 * the file OSO001.MSG in the \OS2 directory hierarchy.
412 *
413 **********************************************************************/
414 static char *
415os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
416{
417 APIRET rc;
418 ULONG msglen;
419
420 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
421 Py_BEGIN_ALLOW_THREADS
422 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
423 errorcode, "oso001.msg", &msglen);
424 Py_END_ALLOW_THREADS
425
426 if (rc == NO_ERROR)
427 os2_formatmsg(msgbuf, msglen, reason);
428 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000429 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000430 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000431
432 return msgbuf;
433}
434
435/* Set an OS/2-specific error and return NULL. OS/2 kernel
436 errors are not in a global variable e.g. 'errno' nor are
437 they congruent with posix error numbers. */
438
439static PyObject * os2_error(int code)
440{
441 char text[1024];
442 PyObject *v;
443
444 os2_strerror(text, sizeof(text), code, "");
445
446 v = Py_BuildValue("(is)", code, text);
447 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000448 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000449 Py_DECREF(v);
450 }
451 return NULL; /* Signal to Python that an Exception is Pending */
452}
453
454#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455
456/* POSIX generic methods */
457
Barry Warsaw53699e91996-12-10 23:23:01 +0000458static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000459posix_fildes(PyObject *fdobj, int (*func)(int))
460{
461 int fd;
462 int res;
463 fd = PyObject_AsFileDescriptor(fdobj);
464 if (fd < 0)
465 return NULL;
466 Py_BEGIN_ALLOW_THREADS
467 res = (*func)(fd);
468 Py_END_ALLOW_THREADS
469 if (res < 0)
470 return posix_error();
471 Py_INCREF(Py_None);
472 return Py_None;
473}
Guido van Rossum21142a01999-01-08 21:05:37 +0000474
475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000476posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000477{
Mark Hammondef8b6542001-05-13 08:04:26 +0000478 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000479 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000480 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000481 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000483 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000484 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000485 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000486 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000487 return posix_error_with_allocated_filename(path1);
488 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000489 Py_INCREF(Py_None);
490 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000491}
492
Barry Warsaw53699e91996-12-10 23:23:01 +0000493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000494posix_2str(PyObject *args, char *format,
495 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000496{
Mark Hammondef8b6542001-05-13 08:04:26 +0000497 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000498 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000499 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000500 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000501 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000503 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000504 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000505 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000506 PyMem_Free(path1);
507 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000508 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000509 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000510 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000511 Py_INCREF(Py_None);
512 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513}
514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000515PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000516"stat_result: Result from stat or lstat.\n\n\
517This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000518 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000519or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
520\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000521Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000522they are available as attributes only.\n\
523\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000525
526static PyStructSequence_Field stat_result_fields[] = {
527 {"st_mode", "protection bits"},
528 {"st_ino", "inode"},
529 {"st_dev", "device"},
530 {"st_nlink", "number of hard links"},
531 {"st_uid", "user ID of owner"},
532 {"st_gid", "group ID of owner"},
533 {"st_size", "total size, in bytes"},
534 {"st_atime", "time of last access"},
535 {"st_mtime", "time of last modification"},
536 {"st_ctime", "time of last change"},
537#ifdef HAVE_ST_BLKSIZE
538 {"st_blksize", "blocksize for filesystem I/O"},
539#endif
540#ifdef HAVE_ST_BLOCKS
541 {"st_blocks", "number of blocks allocated"},
542#endif
543#ifdef HAVE_ST_RDEV
544 {"st_rdev", "device type (if inode device)"},
545#endif
546 {0}
547};
548
549#ifdef HAVE_ST_BLKSIZE
550#define ST_BLKSIZE_IDX 10
551#else
552#define ST_BLKSIZE_IDX 9
553#endif
554
555#ifdef HAVE_ST_BLOCKS
556#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
557#else
558#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
559#endif
560
561#ifdef HAVE_ST_RDEV
562#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
563#else
564#define ST_RDEV_IDX ST_BLOCKS_IDX
565#endif
566
567static PyStructSequence_Desc stat_result_desc = {
568 "stat_result", /* name */
569 stat_result__doc__, /* doc */
570 stat_result_fields,
571 10
572};
573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000574PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000575"statvfs_result: Result from statvfs or fstatvfs.\n\n\
576This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000577 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000578or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000579\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000580See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000581
582static PyStructSequence_Field statvfs_result_fields[] = {
583 {"f_bsize", },
584 {"f_frsize", },
585 {"f_blocks", },
586 {"f_bfree", },
587 {"f_bavail", },
588 {"f_files", },
589 {"f_ffree", },
590 {"f_favail", },
591 {"f_flag", },
592 {"f_namemax",},
593 {0}
594};
595
596static PyStructSequence_Desc statvfs_result_desc = {
597 "statvfs_result", /* name */
598 statvfs_result__doc__, /* doc */
599 statvfs_result_fields,
600 10
601};
602
603static PyTypeObject StatResultType;
604static PyTypeObject StatVFSResultType;
605
Tim Peters5aa91602002-01-30 05:46:57 +0000606/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000607 (used by posix_stat() and posix_fstat()) */
608static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000609_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000610{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000611 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000612 if (v == NULL)
613 return NULL;
614
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000615 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000616#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000617 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000618 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000619#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000620 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000621#endif
622#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000623 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000624 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000625#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000626 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000627#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000628 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
629 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
630 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000631#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000632 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000633 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000634#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000635 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000636#endif
637#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000638 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000639 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000640 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000641 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000642 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000643 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000644#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000645 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
646 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
647 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
648#endif
649
650#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000651 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000652 PyInt_FromLong((long)st.st_blksize));
653#endif
654#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000655 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000656 PyInt_FromLong((long)st.st_blocks));
657#endif
658#ifdef HAVE_ST_RDEV
659 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
660 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000661#endif
662
663 if (PyErr_Occurred()) {
664 Py_DECREF(v);
665 return NULL;
666 }
667
668 return v;
669}
670
Barry Warsaw53699e91996-12-10 23:23:01 +0000671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000672posix_do_stat(PyObject *self, PyObject *args, char *format,
673 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000674{
Fred Drake699f3522000-06-29 21:12:41 +0000675 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000676 char *path = NULL; /* pass this to stat; do not free() it */
677 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000678 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000679
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000680#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000681 int pathlen;
682 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000683#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000684
Tim Peters5aa91602002-01-30 05:46:57 +0000685 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000686 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000687 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000688 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000689
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000690#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000691 pathlen = strlen(path);
692 /* the library call can blow up if the file name is too long! */
693 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000694 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000695 errno = ENAMETOOLONG;
696 return posix_error();
697 }
698
Tim Peters500bd032001-12-19 19:05:01 +0000699 /* Remove trailing slash or backslash, unless it's the current
700 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
701 */
702 if (pathlen > 0 &&
703 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
704 /* It does end with a slash -- exempt the root drive cases. */
705 /* XXX UNC root drives should also be exempted? */
706 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
707 /* leave it alone */;
708 else {
709 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000710 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000711 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000712 path = pathcopy;
713 }
714 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000715#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000716
Barry Warsaw53699e91996-12-10 23:23:01 +0000717 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000718 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000719 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000720 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000721 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000722
Tim Peters500bd032001-12-19 19:05:01 +0000723 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000724 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725}
726
727
728/* POSIX methods */
729
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000730PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000731"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000732Use the real uid/gid to test for access to a path. Note that most\n\
733operations will use the effective uid/gid, therefore this routine can\n\
734be used in a suid/sgid environment to test if the invoking user has the\n\
735specified access to the path. The mode argument can be F_OK to test\n\
736existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000737
738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000739posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000740{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000741 char *path;
742 int mode;
743 int res;
744
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000745 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000746 return NULL;
747 Py_BEGIN_ALLOW_THREADS
748 res = access(path, mode);
749 Py_END_ALLOW_THREADS
750 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000751}
752
Guido van Rossumd371ff11999-01-25 16:12:23 +0000753#ifndef F_OK
754#define F_OK 0
755#endif
756#ifndef R_OK
757#define R_OK 4
758#endif
759#ifndef W_OK
760#define W_OK 2
761#endif
762#ifndef X_OK
763#define X_OK 1
764#endif
765
766#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000767PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000768"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000769Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000770
771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000772posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000773{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000774 int id;
775 char *ret;
776
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000777 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000778 return NULL;
779
Guido van Rossum94f6f721999-01-06 18:42:14 +0000780 ret = ttyname(id);
781 if (ret == NULL)
782 return(posix_error());
783 return(PyString_FromString(ret));
784}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000785#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000786
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000787#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000788PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000789"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000790Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000791
792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000793posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000794{
795 char *ret;
796 char buffer[L_ctermid];
797
798 if (!PyArg_ParseTuple(args, ":ctermid"))
799 return NULL;
800
Greg Wardb48bc172000-03-01 21:51:56 +0000801#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000802 ret = ctermid_r(buffer);
803#else
804 ret = ctermid(buffer);
805#endif
806 if (ret == NULL)
807 return(posix_error());
808 return(PyString_FromString(buffer));
809}
810#endif
811
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000812PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000813"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000814Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000815
Barry Warsaw53699e91996-12-10 23:23:01 +0000816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000817posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000819#if defined(PYOS_OS2) && defined(PYCC_GCC)
820 return posix_1str(args, "et:chdir", _chdir2);
821#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000822 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000823#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824}
825
Fred Drake4d1e64b2002-04-15 19:40:07 +0000826#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000827PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000828"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +0000829Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000830opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +0000831
832static PyObject *
833posix_fchdir(PyObject *self, PyObject *fdobj)
834{
835 return posix_fildes(fdobj, fchdir);
836}
837#endif /* HAVE_FCHDIR */
838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000839
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000840PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000841"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000842Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000843
Barry Warsaw53699e91996-12-10 23:23:01 +0000844static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000845posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846{
Mark Hammondef8b6542001-05-13 08:04:26 +0000847 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000848 int i;
849 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000850 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000851 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000852 return NULL;
853 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000854 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000855 Py_END_ALLOW_THREADS
856 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000857 return posix_error_with_allocated_filename(path);
858 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000859 Py_INCREF(Py_None);
860 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861}
862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000863
Martin v. Löwis244edc82001-10-04 22:44:26 +0000864#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000865PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000866"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000867Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +0000868
869static PyObject *
870posix_chroot(PyObject *self, PyObject *args)
871{
872 return posix_1str(args, "et:chroot", chroot);
873}
874#endif
875
Guido van Rossum21142a01999-01-08 21:05:37 +0000876#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000877PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000878"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000879force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000880
881static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000882posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000883{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000884 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000885}
886#endif /* HAVE_FSYNC */
887
888#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000889
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000890#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000891extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
892#endif
893
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000894PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000895"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +0000896force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000897 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000898
899static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000900posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000901{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000902 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000903}
904#endif /* HAVE_FDATASYNC */
905
906
Fredrik Lundh10723342000-07-10 16:38:09 +0000907#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000908PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000909"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000910Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000911
Barry Warsaw53699e91996-12-10 23:23:01 +0000912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000913posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000914{
Mark Hammondef8b6542001-05-13 08:04:26 +0000915 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000916 int uid, gid;
917 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000918 if (!PyArg_ParseTuple(args, "etii:chown",
919 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000920 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000921 return NULL;
922 Py_BEGIN_ALLOW_THREADS
923 res = chown(path, (uid_t) uid, (gid_t) gid);
924 Py_END_ALLOW_THREADS
925 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000926 return posix_error_with_allocated_filename(path);
927 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000928 Py_INCREF(Py_None);
929 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000930}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000931#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000933
Guido van Rossum36bc6801995-06-14 22:54:23 +0000934#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000935PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000936"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000937Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000938
Barry Warsaw53699e91996-12-10 23:23:01 +0000939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000940posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000941{
942 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000943 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000944 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000945 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000946 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000947#if defined(PYOS_OS2) && defined(PYCC_GCC)
948 res = _getcwd2(buf, sizeof buf);
949#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000950 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000951#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000952 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000953 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000955 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000957#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000959
Guido van Rossumb6775db1994-08-01 11:34:53 +0000960#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000961PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000962"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000963Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000964
Barry Warsaw53699e91996-12-10 23:23:01 +0000965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000966posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000967{
Mark Hammondef8b6542001-05-13 08:04:26 +0000968 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000969}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000970#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000972
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000973PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000974"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000975Return a list containing the names of the entries in the directory.\n\
976\n\
977 path: path of directory to list\n\
978\n\
979The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000980entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000981
Barry Warsaw53699e91996-12-10 23:23:01 +0000982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000983posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000984{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000985 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000986 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000987#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000988
Barry Warsaw53699e91996-12-10 23:23:01 +0000989 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000990 HANDLE hFindFile;
991 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000992 /* MAX_PATH characters could mean a bigger encoded string */
993 char namebuf[MAX_PATH*2+5];
994 char *bufptr = namebuf;
995 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000996
Tim Peters5aa91602002-01-30 05:46:57 +0000997 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +0000998 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000999 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001000 if (len > 0) {
1001 char ch = namebuf[len-1];
1002 if (ch != SEP && ch != ALTSEP && ch != ':')
1003 namebuf[len++] = '/';
1004 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001005 strcpy(namebuf + len, "*.*");
1006
Barry Warsaw53699e91996-12-10 23:23:01 +00001007 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001008 return NULL;
1009
1010 hFindFile = FindFirstFile(namebuf, &FileData);
1011 if (hFindFile == INVALID_HANDLE_VALUE) {
1012 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001013 if (errno == ERROR_FILE_NOT_FOUND)
1014 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001015 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001016 }
1017 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001018 if (FileData.cFileName[0] == '.' &&
1019 (FileData.cFileName[1] == '\0' ||
1020 FileData.cFileName[1] == '.' &&
1021 FileData.cFileName[2] == '\0'))
1022 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001023 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001024 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001025 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001026 d = NULL;
1027 break;
1028 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001029 if (PyList_Append(d, v) != 0) {
1030 Py_DECREF(v);
1031 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001032 d = NULL;
1033 break;
1034 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001035 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001036 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1037
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001038 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001039 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001040
1041 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001042
Tim Peters0bb44a42000-09-15 07:44:49 +00001043#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001044
1045#ifndef MAX_PATH
1046#define MAX_PATH CCHMAXPATH
1047#endif
1048 char *name, *pt;
1049 int len;
1050 PyObject *d, *v;
1051 char namebuf[MAX_PATH+5];
1052 HDIR hdir = 1;
1053 ULONG srchcnt = 1;
1054 FILEFINDBUF3 ep;
1055 APIRET rc;
1056
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001057 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001058 return NULL;
1059 if (len >= MAX_PATH) {
1060 PyErr_SetString(PyExc_ValueError, "path too long");
1061 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 Rossum8e9ebfd1997-11-22 21:53:48 +00001069 strcpy(namebuf + len, "*.*");
1070
1071 if ((d = PyList_New(0)) == NULL)
1072 return NULL;
1073
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001074 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1075 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001076 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001077 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1078 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1079 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001080
1081 if (rc != NO_ERROR) {
1082 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001083 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001084 }
1085
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001086 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001087 do {
1088 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001089 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001090 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001091
1092 strcpy(namebuf, ep.achName);
1093
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001094 /* Leave Case of Name Alone -- In Native Form */
1095 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001096
1097 v = PyString_FromString(namebuf);
1098 if (v == NULL) {
1099 Py_DECREF(d);
1100 d = NULL;
1101 break;
1102 }
1103 if (PyList_Append(d, v) != 0) {
1104 Py_DECREF(v);
1105 Py_DECREF(d);
1106 d = NULL;
1107 break;
1108 }
1109 Py_DECREF(v);
1110 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1111 }
1112
1113 return d;
1114#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001115
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001116 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001117 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001118 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001119 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001120 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001121 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001122 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001123 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001124 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001125 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001126 closedir(dirp);
1127 return NULL;
1128 }
1129 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001130 if (ep->d_name[0] == '.' &&
1131 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001132 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001133 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001134 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001136 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137 d = NULL;
1138 break;
1139 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001140 if (PyList_Append(d, v) != 0) {
1141 Py_DECREF(v);
1142 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001143 d = NULL;
1144 break;
1145 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001146 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001147 }
1148 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001149
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001151
Tim Peters0bb44a42000-09-15 07:44:49 +00001152#endif /* which OS */
1153} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001154
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001155#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001156/* A helper function for abspath on win32 */
1157static PyObject *
1158posix__getfullpathname(PyObject *self, PyObject *args)
1159{
1160 /* assume encoded strings wont more than double no of chars */
1161 char inbuf[MAX_PATH*2];
1162 char *inbufp = inbuf;
1163 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1164 char outbuf[MAX_PATH*2];
1165 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001166 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1167 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001168 &insize))
1169 return NULL;
1170 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1171 outbuf, &temp))
1172 return win32_error("GetFullPathName", inbuf);
1173 return PyString_FromString(outbuf);
1174} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001175#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001176
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001177PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001178"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001179Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001180
Barry Warsaw53699e91996-12-10 23:23:01 +00001181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001182posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001183{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001184 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001185 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001186 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001187 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001188 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001189 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001190 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001191#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001192 res = mkdir(path);
1193#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001194 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001195#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001196 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001197 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001198 return posix_error_with_allocated_filename(path);
1199 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001200 Py_INCREF(Py_None);
1201 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001202}
1203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001204
Guido van Rossumb6775db1994-08-01 11:34:53 +00001205#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001206#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1207#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1208#include <sys/resource.h>
1209#endif
1210#endif
1211
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001212PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001213"nice(inc) -> new_priority\n\n\
1214Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001215
Barry Warsaw53699e91996-12-10 23:23:01 +00001216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001217posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001218{
1219 int increment, value;
1220
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001221 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001222 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001223
1224 /* There are two flavours of 'nice': one that returns the new
1225 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001226 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1227 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001228
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001229 If we are of the nice family that returns the new priority, we
1230 need to clear errno before the call, and check if errno is filled
1231 before calling posix_error() on a returnvalue of -1, because the
1232 -1 may be the actual new priority! */
1233
1234 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001235 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001236#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001237 if (value == 0)
1238 value = getpriority(PRIO_PROCESS, 0);
1239#endif
1240 if (value == -1 && errno != 0)
1241 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001242 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001243 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001244}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001245#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001246
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001248PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001249"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001250Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001251
Barry Warsaw53699e91996-12-10 23:23:01 +00001252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001253posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254{
Mark Hammondef8b6542001-05-13 08:04:26 +00001255 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001256}
1257
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001258
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001259PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001260"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001261Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001262
Barry Warsaw53699e91996-12-10 23:23:01 +00001263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001264posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001265{
Mark Hammondef8b6542001-05-13 08:04:26 +00001266 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001269
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001270PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001271"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001272Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001273
Barry Warsaw53699e91996-12-10 23:23:01 +00001274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001275posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001276{
Mark Hammondef8b6542001-05-13 08:04:26 +00001277 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001278}
1279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001280
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001281#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001282PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001283"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001284Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001285
Barry Warsaw53699e91996-12-10 23:23:01 +00001286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001287posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001288{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001289 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001290 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001291 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001293 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001294 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001295 Py_END_ALLOW_THREADS
1296 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001297}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001298#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001300
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001301PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001302"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001303Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001304
Barry Warsaw53699e91996-12-10 23:23:01 +00001305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001306posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307{
1308 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001309 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001311 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312 if (i < 0)
1313 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001314 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001315}
1316
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001317
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001318PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001319"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001320Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001321
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001322PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001323"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001324Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001325
Barry Warsaw53699e91996-12-10 23:23:01 +00001326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001327posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001328{
Mark Hammondef8b6542001-05-13 08:04:26 +00001329 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001330}
1331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001332
Guido van Rossumb6775db1994-08-01 11:34:53 +00001333#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001334PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001335"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001336Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001337
Barry Warsaw53699e91996-12-10 23:23:01 +00001338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001339posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001340{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001341 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001342 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001343 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001344 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001345 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001346 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001347 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001348 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001349 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001350 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001351 u.sysname,
1352 u.nodename,
1353 u.release,
1354 u.version,
1355 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001356}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001357#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001358
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001359
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001360PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001361"utime(path, (atime, utime))\n\
1362utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001363Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001364second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001365
Barry Warsaw53699e91996-12-10 23:23:01 +00001366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001367posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001368{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001369 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001370 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001371 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001372 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001373
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001374/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001375#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001376 struct utimbuf buf;
1377#define ATIME buf.actime
1378#define MTIME buf.modtime
1379#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001380#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001381 time_t buf[2];
1382#define ATIME buf[0]
1383#define MTIME buf[1]
1384#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001385#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001386
Barry Warsaw3cef8562000-05-01 16:17:24 +00001387 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001388 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001389 if (arg == Py_None) {
1390 /* optional time values not given */
1391 Py_BEGIN_ALLOW_THREADS
1392 res = utime(path, NULL);
1393 Py_END_ALLOW_THREADS
1394 }
1395 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1396 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001397 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001398 return NULL;
1399 }
1400 else {
1401 ATIME = atime;
1402 MTIME = mtime;
1403 Py_BEGIN_ALLOW_THREADS
1404 res = utime(path, UTIME_ARG);
1405 Py_END_ALLOW_THREADS
1406 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001407 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001408 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001409 Py_INCREF(Py_None);
1410 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001411#undef UTIME_ARG
1412#undef ATIME
1413#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001414}
1415
Guido van Rossum85e3b011991-06-03 12:42:10 +00001416
Guido van Rossum3b066191991-06-04 19:40:25 +00001417/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001418
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001419PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001420"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001421Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001422
Barry Warsaw53699e91996-12-10 23:23:01 +00001423static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001424posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001425{
1426 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001427 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001428 return NULL;
1429 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001430 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001431}
1432
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001433
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001434#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001435PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001436"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001437Execute an executable path with arguments, replacing current process.\n\
1438\n\
1439 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001440 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001441
Barry Warsaw53699e91996-12-10 23:23:01 +00001442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001443posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001444{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001445 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001446 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001447 char **argvlist;
1448 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001449 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001450
Guido van Rossum89b33251993-10-22 14:26:06 +00001451 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001452 argv is a list or tuple of strings. */
1453
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001454 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001455 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001456 if (PyList_Check(argv)) {
1457 argc = PyList_Size(argv);
1458 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001459 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001460 else if (PyTuple_Check(argv)) {
1461 argc = PyTuple_Size(argv);
1462 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001463 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001464 else {
Fred Drake661ea262000-10-24 19:57:45 +00001465 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001466 return NULL;
1467 }
1468
1469 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001470 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001471 return NULL;
1472 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001473
Barry Warsaw53699e91996-12-10 23:23:01 +00001474 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001475 if (argvlist == NULL)
1476 return NULL;
1477 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001478 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1479 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001480 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001481 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001482 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001483
Guido van Rossum85e3b011991-06-03 12:42:10 +00001484 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001485 }
1486 argvlist[argc] = NULL;
1487
Guido van Rossumb6775db1994-08-01 11:34:53 +00001488#ifdef BAD_EXEC_PROTOTYPES
1489 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001490#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001491 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001492#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001493
Guido van Rossum85e3b011991-06-03 12:42:10 +00001494 /* If we get here it's definitely an error */
1495
Barry Warsaw53699e91996-12-10 23:23:01 +00001496 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001497 return posix_error();
1498}
1499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001500
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001501PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001502"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001503Execute a path with arguments and environment, replacing current process.\n\
1504\n\
1505 path: path of executable file\n\
1506 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001507 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001508
Barry Warsaw53699e91996-12-10 23:23:01 +00001509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001510posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001511{
1512 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001513 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001514 char **argvlist;
1515 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001516 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001517 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001518 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001519
1520 /* execve has three arguments: (path, argv, env), where
1521 argv is a list or tuple of strings and env is a dictionary
1522 like posix.environ. */
1523
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001524 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001525 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001526 if (PyList_Check(argv)) {
1527 argc = PyList_Size(argv);
1528 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001529 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001530 else if (PyTuple_Check(argv)) {
1531 argc = PyTuple_Size(argv);
1532 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001533 }
1534 else {
Fred Drake661ea262000-10-24 19:57:45 +00001535 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001536 return NULL;
1537 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001538 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001539 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001540 return NULL;
1541 }
1542
Guido van Rossum50422b42000-04-26 20:34:28 +00001543 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001544 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001545 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001546 return NULL;
1547 }
1548
Barry Warsaw53699e91996-12-10 23:23:01 +00001549 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001550 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001551 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001552 return NULL;
1553 }
1554 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001555 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001556 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001557 &argvlist[i]))
1558 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001559 goto fail_1;
1560 }
1561 }
1562 argvlist[argc] = NULL;
1563
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001564 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001565 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001566 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001567 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001568 goto fail_1;
1569 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001570 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001571 keys = PyMapping_Keys(env);
1572 vals = PyMapping_Values(env);
1573 if (!keys || !vals)
1574 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001575
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001576 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001577 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001578 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001579
1580 key = PyList_GetItem(keys, pos);
1581 val = PyList_GetItem(vals, pos);
1582 if (!key || !val)
1583 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001584
Fred Drake661ea262000-10-24 19:57:45 +00001585 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1586 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001587 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001588 goto fail_2;
1589 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001590
1591#if defined(PYOS_OS2)
1592 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1593 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1594#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001595 len = PyString_Size(key) + PyString_Size(val) + 2;
1596 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001597 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001598 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001599 goto fail_2;
1600 }
Tim Petersc8996f52001-12-03 20:41:00 +00001601 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001602 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001603#if defined(PYOS_OS2)
1604 }
1605#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001606 }
1607 envlist[envc] = 0;
1608
Guido van Rossumb6775db1994-08-01 11:34:53 +00001609
1610#ifdef BAD_EXEC_PROTOTYPES
1611 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001612#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001613 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001614#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001615
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001616 /* If we get here it's definitely an error */
1617
1618 (void) posix_error();
1619
1620 fail_2:
1621 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001622 PyMem_DEL(envlist[envc]);
1623 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001624 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001625 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001626 Py_XDECREF(vals);
1627 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001628 return NULL;
1629}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001630#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001631
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001632
Guido van Rossuma1065681999-01-25 23:20:23 +00001633#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001634PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001635"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001636Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001637\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001638 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001639 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001640 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001641
1642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001643posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001644{
1645 char *path;
1646 PyObject *argv;
1647 char **argvlist;
1648 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001649 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001650 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001651
1652 /* spawnv has three arguments: (mode, path, argv), where
1653 argv is a list or tuple of strings. */
1654
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001655 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001656 return NULL;
1657 if (PyList_Check(argv)) {
1658 argc = PyList_Size(argv);
1659 getitem = PyList_GetItem;
1660 }
1661 else if (PyTuple_Check(argv)) {
1662 argc = PyTuple_Size(argv);
1663 getitem = PyTuple_GetItem;
1664 }
1665 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001666 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001667 return NULL;
1668 }
1669
1670 argvlist = PyMem_NEW(char *, argc+1);
1671 if (argvlist == NULL)
1672 return NULL;
1673 for (i = 0; i < argc; i++) {
1674 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1675 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001676 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001677 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001678 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001679 }
1680 }
1681 argvlist[argc] = NULL;
1682
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001683#if defined(PYOS_OS2) && defined(PYCC_GCC)
1684 Py_BEGIN_ALLOW_THREADS
1685 spawnval = spawnv(mode, path, argvlist);
1686 Py_END_ALLOW_THREADS
1687#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001688 if (mode == _OLD_P_OVERLAY)
1689 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001690
Tim Peters25059d32001-12-07 20:35:43 +00001691 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001692 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001693 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001694#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001695
Guido van Rossuma1065681999-01-25 23:20:23 +00001696 PyMem_DEL(argvlist);
1697
Fred Drake699f3522000-06-29 21:12:41 +00001698 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001699 return posix_error();
1700 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001701#if SIZEOF_LONG == SIZEOF_VOID_P
1702 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001703#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001704 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001705#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001706}
1707
1708
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001709PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001710"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001711Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001712\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001713 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001714 path: path of executable file\n\
1715 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001716 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001717
1718static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001719posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001720{
1721 char *path;
1722 PyObject *argv, *env;
1723 char **argvlist;
1724 char **envlist;
1725 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1726 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001727 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001728 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001729
1730 /* spawnve has four arguments: (mode, path, argv, env), where
1731 argv is a list or tuple of strings and env is a dictionary
1732 like posix.environ. */
1733
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001734 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001735 return NULL;
1736 if (PyList_Check(argv)) {
1737 argc = PyList_Size(argv);
1738 getitem = PyList_GetItem;
1739 }
1740 else if (PyTuple_Check(argv)) {
1741 argc = PyTuple_Size(argv);
1742 getitem = PyTuple_GetItem;
1743 }
1744 else {
Fred Drake661ea262000-10-24 19:57:45 +00001745 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001746 return NULL;
1747 }
1748 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001749 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001750 return NULL;
1751 }
1752
1753 argvlist = PyMem_NEW(char *, argc+1);
1754 if (argvlist == NULL) {
1755 PyErr_NoMemory();
1756 return NULL;
1757 }
1758 for (i = 0; i < argc; i++) {
1759 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001760 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001761 &argvlist[i]))
1762 {
1763 goto fail_1;
1764 }
1765 }
1766 argvlist[argc] = NULL;
1767
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001768 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001769 envlist = PyMem_NEW(char *, i + 1);
1770 if (envlist == NULL) {
1771 PyErr_NoMemory();
1772 goto fail_1;
1773 }
1774 envc = 0;
1775 keys = PyMapping_Keys(env);
1776 vals = PyMapping_Values(env);
1777 if (!keys || !vals)
1778 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001779
Guido van Rossuma1065681999-01-25 23:20:23 +00001780 for (pos = 0; pos < i; pos++) {
1781 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001782 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001783
1784 key = PyList_GetItem(keys, pos);
1785 val = PyList_GetItem(vals, pos);
1786 if (!key || !val)
1787 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001788
Fred Drake661ea262000-10-24 19:57:45 +00001789 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1790 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001791 {
1792 goto fail_2;
1793 }
Tim Petersc8996f52001-12-03 20:41:00 +00001794 len = PyString_Size(key) + PyString_Size(val) + 2;
1795 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001796 if (p == NULL) {
1797 PyErr_NoMemory();
1798 goto fail_2;
1799 }
Tim Petersc8996f52001-12-03 20:41:00 +00001800 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001801 envlist[envc++] = p;
1802 }
1803 envlist[envc] = 0;
1804
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001805#if defined(PYOS_OS2) && defined(PYCC_GCC)
1806 Py_BEGIN_ALLOW_THREADS
1807 spawnval = spawnve(mode, path, argvlist, envlist);
1808 Py_END_ALLOW_THREADS
1809#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001810 if (mode == _OLD_P_OVERLAY)
1811 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001812
1813 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001814 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001815 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001816#endif
Tim Peters25059d32001-12-07 20:35:43 +00001817
Fred Drake699f3522000-06-29 21:12:41 +00001818 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001819 (void) posix_error();
1820 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001821#if SIZEOF_LONG == SIZEOF_VOID_P
1822 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001823#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001824 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001825#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001826
1827 fail_2:
1828 while (--envc >= 0)
1829 PyMem_DEL(envlist[envc]);
1830 PyMem_DEL(envlist);
1831 fail_1:
1832 PyMem_DEL(argvlist);
1833 Py_XDECREF(vals);
1834 Py_XDECREF(keys);
1835 return res;
1836}
1837#endif /* HAVE_SPAWNV */
1838
1839
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001840#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001841PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001842"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001843Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1844\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001845Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001846
1847static PyObject *
1848posix_fork1(self, args)
1849 PyObject *self;
1850 PyObject *args;
1851{
1852 int pid;
1853 if (!PyArg_ParseTuple(args, ":fork1"))
1854 return NULL;
1855 pid = fork1();
1856 if (pid == -1)
1857 return posix_error();
1858 PyOS_AfterFork();
1859 return PyInt_FromLong((long)pid);
1860}
1861#endif
1862
1863
Guido van Rossumad0ee831995-03-01 10:34:45 +00001864#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001865PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001866"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001867Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001868Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001869
Barry Warsaw53699e91996-12-10 23:23:01 +00001870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001871posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001872{
1873 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001874 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001875 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001876 pid = fork();
1877 if (pid == -1)
1878 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001879 if (pid == 0)
1880 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001881 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001882}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001883#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001884
Fred Drake8cef4cf2000-06-28 16:40:38 +00001885#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1886#ifdef HAVE_PTY_H
1887#include <pty.h>
1888#else
1889#ifdef HAVE_LIBUTIL_H
1890#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001891#endif /* HAVE_LIBUTIL_H */
1892#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001893#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001894
Thomas Wouters70c21a12000-07-14 14:28:33 +00001895#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001896PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001897"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001898Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001899
1900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001901posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001902{
1903 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001904#ifndef HAVE_OPENPTY
1905 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001906#endif
1907
Fred Drake8cef4cf2000-06-28 16:40:38 +00001908 if (!PyArg_ParseTuple(args, ":openpty"))
1909 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001910
1911#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001912 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1913 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001914#else
1915 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1916 if (slave_name == NULL)
1917 return posix_error();
1918
1919 slave_fd = open(slave_name, O_RDWR);
1920 if (slave_fd < 0)
1921 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001922#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001923
Fred Drake8cef4cf2000-06-28 16:40:38 +00001924 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001925
Fred Drake8cef4cf2000-06-28 16:40:38 +00001926}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001927#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001928
1929#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001930PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001931"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00001932Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1933Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001934To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001935
1936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001937posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001938{
1939 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00001940
Fred Drake8cef4cf2000-06-28 16:40:38 +00001941 if (!PyArg_ParseTuple(args, ":forkpty"))
1942 return NULL;
1943 pid = forkpty(&master_fd, NULL, NULL, NULL);
1944 if (pid == -1)
1945 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001946 if (pid == 0)
1947 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001948 return Py_BuildValue("(ii)", pid, master_fd);
1949}
1950#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001951
Guido van Rossumad0ee831995-03-01 10:34:45 +00001952#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001954"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001955Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001956
Barry Warsaw53699e91996-12-10 23:23:01 +00001957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001958posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001959{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001960 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001961 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001962 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001963}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001964#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001966
Guido van Rossumad0ee831995-03-01 10:34:45 +00001967#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001969"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001971
Barry Warsaw53699e91996-12-10 23:23:01 +00001972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001973posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001974{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001975 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001976 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001977 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001978}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001979#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001980
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001981
Guido van Rossumad0ee831995-03-01 10:34:45 +00001982#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001983PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001984"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001985Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001986
Barry Warsaw53699e91996-12-10 23:23:01 +00001987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001988posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001989{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001990 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001991 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001992 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001993}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001994#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001995
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001996
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001997PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001998"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001999Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002000
Barry Warsaw53699e91996-12-10 23:23:01 +00002001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002002posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002003{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002004 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002005 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002006 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002007}
2008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002009
Fred Drakec9680921999-12-13 16:37:25 +00002010#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002011PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002012"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002013Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002014
2015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002016posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002017{
2018 PyObject *result = NULL;
2019
2020 if (PyArg_ParseTuple(args, ":getgroups")) {
2021#ifdef NGROUPS_MAX
2022#define MAX_GROUPS NGROUPS_MAX
2023#else
2024 /* defined to be 16 on Solaris7, so this should be a small number */
2025#define MAX_GROUPS 64
2026#endif
2027 gid_t grouplist[MAX_GROUPS];
2028 int n;
2029
2030 n = getgroups(MAX_GROUPS, grouplist);
2031 if (n < 0)
2032 posix_error();
2033 else {
2034 result = PyList_New(n);
2035 if (result != NULL) {
2036 PyObject *o;
2037 int i;
2038 for (i = 0; i < n; ++i) {
2039 o = PyInt_FromLong((long)grouplist[i]);
2040 if (o == NULL) {
2041 Py_DECREF(result);
2042 result = NULL;
2043 break;
2044 }
2045 PyList_SET_ITEM(result, i, o);
2046 }
2047 }
2048 }
2049 }
2050 return result;
2051}
2052#endif
2053
Martin v. Löwis606edc12002-06-13 21:09:11 +00002054#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002055PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002056"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002057Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002058
2059static PyObject *
2060posix_getpgid(PyObject *self, PyObject *args)
2061{
2062 int pid, pgid;
2063 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2064 return NULL;
2065 pgid = getpgid(pid);
2066 if (pgid < 0)
2067 return posix_error();
2068 return PyInt_FromLong((long)pgid);
2069}
2070#endif /* HAVE_GETPGID */
2071
2072
Guido van Rossumb6775db1994-08-01 11:34:53 +00002073#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002075"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002076Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002077
Barry Warsaw53699e91996-12-10 23:23:01 +00002078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002079posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002080{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002081 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002082 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002083#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002084 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002085#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002087#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002088}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002089#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002091
Guido van Rossumb6775db1994-08-01 11:34:53 +00002092#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002093PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002094"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002095Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002096
Barry Warsaw53699e91996-12-10 23:23:01 +00002097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002098posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002099{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002100 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002101 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002102#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002103 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002104#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002105 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002106#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002107 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002108 Py_INCREF(Py_None);
2109 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002110}
2111
Guido van Rossumb6775db1994-08-01 11:34:53 +00002112#endif /* HAVE_SETPGRP */
2113
Guido van Rossumad0ee831995-03-01 10:34:45 +00002114#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002115PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002116"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002117Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002118
Barry Warsaw53699e91996-12-10 23:23:01 +00002119static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002120posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002121{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002122 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002123 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002124 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002125}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002126#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002128
Fred Drake12c6e2d1999-12-14 21:25:03 +00002129#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002130PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002131"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002132Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002133
2134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002135posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002136{
2137 PyObject *result = NULL;
2138
2139 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002140 char *name;
2141 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002142
Fred Drakea30680b2000-12-06 21:24:28 +00002143 errno = 0;
2144 name = getlogin();
2145 if (name == NULL) {
2146 if (errno)
2147 posix_error();
2148 else
2149 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002150 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002151 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002152 else
2153 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002154 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002155 }
2156 return result;
2157}
2158#endif
2159
Guido van Rossumad0ee831995-03-01 10:34:45 +00002160#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002161PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002162"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002163Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002164
Barry Warsaw53699e91996-12-10 23:23:01 +00002165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002166posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002167{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002168 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002169 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002170 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002171}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002172#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002173
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002174
Guido van Rossumad0ee831995-03-01 10:34:45 +00002175#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002176PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002177"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002178Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002179
Barry Warsaw53699e91996-12-10 23:23:01 +00002180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002181posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002182{
2183 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002184 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002185 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002186#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002187 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2188 APIRET rc;
2189 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002190 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002191
2192 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2193 APIRET rc;
2194 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002195 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002196
2197 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002198 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002199#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002200 if (kill(pid, sig) == -1)
2201 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002202#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002203 Py_INCREF(Py_None);
2204 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002205}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002206#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002207
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002208#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002209PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002210"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002211Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002212
2213static PyObject *
2214posix_killpg(PyObject *self, PyObject *args)
2215{
2216 int pgid, sig;
2217 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2218 return NULL;
2219 if (killpg(pgid, sig) == -1)
2220 return posix_error();
2221 Py_INCREF(Py_None);
2222 return Py_None;
2223}
2224#endif
2225
Guido van Rossumc0125471996-06-28 18:55:32 +00002226#ifdef HAVE_PLOCK
2227
2228#ifdef HAVE_SYS_LOCK_H
2229#include <sys/lock.h>
2230#endif
2231
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002232PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002233"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002234Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002235
Barry Warsaw53699e91996-12-10 23:23:01 +00002236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002237posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002238{
2239 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002240 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002241 return NULL;
2242 if (plock(op) == -1)
2243 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002244 Py_INCREF(Py_None);
2245 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002246}
2247#endif
2248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002249
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002250#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002251PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002252"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002253Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002254
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002255#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002256#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002257static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002258async_system(const char *command)
2259{
2260 char *p, errormsg[256], args[1024];
2261 RESULTCODES rcodes;
2262 APIRET rc;
2263 char *shell = getenv("COMSPEC");
2264 if (!shell)
2265 shell = "cmd";
2266
2267 strcpy(args, shell);
2268 p = &args[ strlen(args)+1 ];
2269 strcpy(p, "/c ");
2270 strcat(p, command);
2271 p += strlen(p) + 1;
2272 *p = '\0';
2273
2274 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002275 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002276 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002277 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002278 &rcodes, shell);
2279 return rc;
2280}
2281
Guido van Rossumd48f2521997-12-05 22:19:34 +00002282static FILE *
2283popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002284{
2285 HFILE rhan, whan;
2286 FILE *retfd = NULL;
2287 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2288
Guido van Rossumd48f2521997-12-05 22:19:34 +00002289 if (rc != NO_ERROR) {
2290 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002291 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002292 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002293
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002294 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2295 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002296
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002297 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2298 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002299
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002300 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2301 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002302
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002303 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002304 }
2305
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002306 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2307 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002308
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002309 if (rc == NO_ERROR)
2310 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2311
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002312 close(oldfd); /* And Close Saved STDOUT Handle */
2313 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002314
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002315 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2316 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002317
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002318 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2319 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002320
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002321 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2322 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002324 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002325 }
2326
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002327 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2328 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002329
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002330 if (rc == NO_ERROR)
2331 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2332
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002333 close(oldfd); /* And Close Saved STDIN Handle */
2334 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002335
Guido van Rossumd48f2521997-12-05 22:19:34 +00002336 } else {
2337 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002338 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002339 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002340}
2341
2342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002343posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002344{
2345 char *name;
2346 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002347 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002348 FILE *fp;
2349 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002350 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002351 return NULL;
2352 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002353 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002354 Py_END_ALLOW_THREADS
2355 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002356 return os2_error(err);
2357
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002358 f = PyFile_FromFile(fp, name, mode, fclose);
2359 if (f != NULL)
2360 PyFile_SetBufSize(f, bufsize);
2361 return f;
2362}
2363
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002364#elif defined(PYCC_GCC)
2365
2366/* standard posix version of popen() support */
2367static PyObject *
2368posix_popen(PyObject *self, PyObject *args)
2369{
2370 char *name;
2371 char *mode = "r";
2372 int bufsize = -1;
2373 FILE *fp;
2374 PyObject *f;
2375 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2376 return NULL;
2377 Py_BEGIN_ALLOW_THREADS
2378 fp = popen(name, mode);
2379 Py_END_ALLOW_THREADS
2380 if (fp == NULL)
2381 return posix_error();
2382 f = PyFile_FromFile(fp, name, mode, pclose);
2383 if (f != NULL)
2384 PyFile_SetBufSize(f, bufsize);
2385 return f;
2386}
2387
2388/* fork() under OS/2 has lots'o'warts
2389 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2390 * most of this code is a ripoff of the win32 code, but using the
2391 * capabilities of EMX's C library routines
2392 */
2393
2394/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2395#define POPEN_1 1
2396#define POPEN_2 2
2397#define POPEN_3 3
2398#define POPEN_4 4
2399
2400static PyObject *_PyPopen(char *, int, int, int);
2401static int _PyPclose(FILE *file);
2402
2403/*
2404 * Internal dictionary mapping popen* file pointers to process handles,
2405 * for use when retrieving the process exit code. See _PyPclose() below
2406 * for more information on this dictionary's use.
2407 */
2408static PyObject *_PyPopenProcs = NULL;
2409
2410/* os2emx version of popen2()
2411 *
2412 * The result of this function is a pipe (file) connected to the
2413 * process's stdin, and a pipe connected to the process's stdout.
2414 */
2415
2416static PyObject *
2417os2emx_popen2(PyObject *self, PyObject *args)
2418{
2419 PyObject *f;
2420 int tm=0;
2421
2422 char *cmdstring;
2423 char *mode = "t";
2424 int bufsize = -1;
2425 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2426 return NULL;
2427
2428 if (*mode == 't')
2429 tm = O_TEXT;
2430 else if (*mode != 'b') {
2431 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2432 return NULL;
2433 } else
2434 tm = O_BINARY;
2435
2436 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2437
2438 return f;
2439}
2440
2441/*
2442 * Variation on os2emx.popen2
2443 *
2444 * The result of this function is 3 pipes - the process's stdin,
2445 * stdout and stderr
2446 */
2447
2448static PyObject *
2449os2emx_popen3(PyObject *self, PyObject *args)
2450{
2451 PyObject *f;
2452 int tm = 0;
2453
2454 char *cmdstring;
2455 char *mode = "t";
2456 int bufsize = -1;
2457 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2458 return NULL;
2459
2460 if (*mode == 't')
2461 tm = O_TEXT;
2462 else if (*mode != 'b') {
2463 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2464 return NULL;
2465 } else
2466 tm = O_BINARY;
2467
2468 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2469
2470 return f;
2471}
2472
2473/*
2474 * Variation on os2emx.popen2
2475 *
2476 * The result of this function is 2 pipes - the processes stdin,
2477 * and stdout+stderr combined as a single pipe.
2478 */
2479
2480static PyObject *
2481os2emx_popen4(PyObject *self, PyObject *args)
2482{
2483 PyObject *f;
2484 int tm = 0;
2485
2486 char *cmdstring;
2487 char *mode = "t";
2488 int bufsize = -1;
2489 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2490 return NULL;
2491
2492 if (*mode == 't')
2493 tm = O_TEXT;
2494 else if (*mode != 'b') {
2495 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2496 return NULL;
2497 } else
2498 tm = O_BINARY;
2499
2500 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2501
2502 return f;
2503}
2504
2505/* a couple of structures for convenient handling of multiple
2506 * file handles and pipes
2507 */
2508struct file_ref
2509{
2510 int handle;
2511 int flags;
2512};
2513
2514struct pipe_ref
2515{
2516 int rd;
2517 int wr;
2518};
2519
2520/* The following code is derived from the win32 code */
2521
2522static PyObject *
2523_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2524{
2525 struct file_ref stdio[3];
2526 struct pipe_ref p_fd[3];
2527 FILE *p_s[3];
2528 int file_count, i, pipe_err, pipe_pid;
2529 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2530 PyObject *f, *p_f[3];
2531
2532 /* file modes for subsequent fdopen's on pipe handles */
2533 if (mode == O_TEXT)
2534 {
2535 rd_mode = "rt";
2536 wr_mode = "wt";
2537 }
2538 else
2539 {
2540 rd_mode = "rb";
2541 wr_mode = "wb";
2542 }
2543
2544 /* prepare shell references */
2545 if ((shell = getenv("EMXSHELL")) == NULL)
2546 if ((shell = getenv("COMSPEC")) == NULL)
2547 {
2548 errno = ENOENT;
2549 return posix_error();
2550 }
2551
2552 sh_name = _getname(shell);
2553 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2554 opt = "/c";
2555 else
2556 opt = "-c";
2557
2558 /* save current stdio fds + their flags, and set not inheritable */
2559 i = pipe_err = 0;
2560 while (pipe_err >= 0 && i < 3)
2561 {
2562 pipe_err = stdio[i].handle = dup(i);
2563 stdio[i].flags = fcntl(i, F_GETFD, 0);
2564 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2565 i++;
2566 }
2567 if (pipe_err < 0)
2568 {
2569 /* didn't get them all saved - clean up and bail out */
2570 int saved_err = errno;
2571 while (i-- > 0)
2572 {
2573 close(stdio[i].handle);
2574 }
2575 errno = saved_err;
2576 return posix_error();
2577 }
2578
2579 /* create pipe ends */
2580 file_count = 2;
2581 if (n == POPEN_3)
2582 file_count = 3;
2583 i = pipe_err = 0;
2584 while ((pipe_err == 0) && (i < file_count))
2585 pipe_err = pipe((int *)&p_fd[i++]);
2586 if (pipe_err < 0)
2587 {
2588 /* didn't get them all made - clean up and bail out */
2589 while (i-- > 0)
2590 {
2591 close(p_fd[i].wr);
2592 close(p_fd[i].rd);
2593 }
2594 errno = EPIPE;
2595 return posix_error();
2596 }
2597
2598 /* change the actual standard IO streams over temporarily,
2599 * making the retained pipe ends non-inheritable
2600 */
2601 pipe_err = 0;
2602
2603 /* - stdin */
2604 if (dup2(p_fd[0].rd, 0) == 0)
2605 {
2606 close(p_fd[0].rd);
2607 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2608 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2609 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2610 {
2611 close(p_fd[0].wr);
2612 pipe_err = -1;
2613 }
2614 }
2615 else
2616 {
2617 pipe_err = -1;
2618 }
2619
2620 /* - stdout */
2621 if (pipe_err == 0)
2622 {
2623 if (dup2(p_fd[1].wr, 1) == 1)
2624 {
2625 close(p_fd[1].wr);
2626 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2627 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2628 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2629 {
2630 close(p_fd[1].rd);
2631 pipe_err = -1;
2632 }
2633 }
2634 else
2635 {
2636 pipe_err = -1;
2637 }
2638 }
2639
2640 /* - stderr, as required */
2641 if (pipe_err == 0)
2642 switch (n)
2643 {
2644 case POPEN_3:
2645 {
2646 if (dup2(p_fd[2].wr, 2) == 2)
2647 {
2648 close(p_fd[2].wr);
2649 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2650 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2651 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2652 {
2653 close(p_fd[2].rd);
2654 pipe_err = -1;
2655 }
2656 }
2657 else
2658 {
2659 pipe_err = -1;
2660 }
2661 break;
2662 }
2663
2664 case POPEN_4:
2665 {
2666 if (dup2(1, 2) != 2)
2667 {
2668 pipe_err = -1;
2669 }
2670 break;
2671 }
2672 }
2673
2674 /* spawn the child process */
2675 if (pipe_err == 0)
2676 {
2677 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2678 if (pipe_pid == -1)
2679 {
2680 pipe_err = -1;
2681 }
2682 else
2683 {
2684 /* save the PID into the FILE structure
2685 * NOTE: this implementation doesn't actually
2686 * take advantage of this, but do it for
2687 * completeness - AIM Apr01
2688 */
2689 for (i = 0; i < file_count; i++)
2690 p_s[i]->_pid = pipe_pid;
2691 }
2692 }
2693
2694 /* reset standard IO to normal */
2695 for (i = 0; i < 3; i++)
2696 {
2697 dup2(stdio[i].handle, i);
2698 fcntl(i, F_SETFD, stdio[i].flags);
2699 close(stdio[i].handle);
2700 }
2701
2702 /* if any remnant problems, clean up and bail out */
2703 if (pipe_err < 0)
2704 {
2705 for (i = 0; i < 3; i++)
2706 {
2707 close(p_fd[i].rd);
2708 close(p_fd[i].wr);
2709 }
2710 errno = EPIPE;
2711 return posix_error_with_filename(cmdstring);
2712 }
2713
2714 /* build tuple of file objects to return */
2715 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2716 PyFile_SetBufSize(p_f[0], bufsize);
2717 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2718 PyFile_SetBufSize(p_f[1], bufsize);
2719 if (n == POPEN_3)
2720 {
2721 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2722 PyFile_SetBufSize(p_f[0], bufsize);
2723 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2724 }
2725 else
2726 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2727
2728 /*
2729 * Insert the files we've created into the process dictionary
2730 * all referencing the list with the process handle and the
2731 * initial number of files (see description below in _PyPclose).
2732 * Since if _PyPclose later tried to wait on a process when all
2733 * handles weren't closed, it could create a deadlock with the
2734 * child, we spend some energy here to try to ensure that we
2735 * either insert all file handles into the dictionary or none
2736 * at all. It's a little clumsy with the various popen modes
2737 * and variable number of files involved.
2738 */
2739 if (!_PyPopenProcs)
2740 {
2741 _PyPopenProcs = PyDict_New();
2742 }
2743
2744 if (_PyPopenProcs)
2745 {
2746 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2747 int ins_rc[3];
2748
2749 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2750 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2751
2752 procObj = PyList_New(2);
2753 pidObj = PyInt_FromLong((long) pipe_pid);
2754 intObj = PyInt_FromLong((long) file_count);
2755
2756 if (procObj && pidObj && intObj)
2757 {
2758 PyList_SetItem(procObj, 0, pidObj);
2759 PyList_SetItem(procObj, 1, intObj);
2760
2761 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2762 if (fileObj[0])
2763 {
2764 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2765 fileObj[0],
2766 procObj);
2767 }
2768 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2769 if (fileObj[1])
2770 {
2771 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2772 fileObj[1],
2773 procObj);
2774 }
2775 if (file_count >= 3)
2776 {
2777 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2778 if (fileObj[2])
2779 {
2780 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2781 fileObj[2],
2782 procObj);
2783 }
2784 }
2785
2786 if (ins_rc[0] < 0 || !fileObj[0] ||
2787 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2788 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2789 {
2790 /* Something failed - remove any dictionary
2791 * entries that did make it.
2792 */
2793 if (!ins_rc[0] && fileObj[0])
2794 {
2795 PyDict_DelItem(_PyPopenProcs,
2796 fileObj[0]);
2797 }
2798 if (!ins_rc[1] && fileObj[1])
2799 {
2800 PyDict_DelItem(_PyPopenProcs,
2801 fileObj[1]);
2802 }
2803 if (!ins_rc[2] && fileObj[2])
2804 {
2805 PyDict_DelItem(_PyPopenProcs,
2806 fileObj[2]);
2807 }
2808 }
2809 }
2810
2811 /*
2812 * Clean up our localized references for the dictionary keys
2813 * and value since PyDict_SetItem will Py_INCREF any copies
2814 * that got placed in the dictionary.
2815 */
2816 Py_XDECREF(procObj);
2817 Py_XDECREF(fileObj[0]);
2818 Py_XDECREF(fileObj[1]);
2819 Py_XDECREF(fileObj[2]);
2820 }
2821
2822 /* Child is launched. */
2823 return f;
2824}
2825
2826/*
2827 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2828 * exit code for the child process and return as a result of the close.
2829 *
2830 * This function uses the _PyPopenProcs dictionary in order to map the
2831 * input file pointer to information about the process that was
2832 * originally created by the popen* call that created the file pointer.
2833 * The dictionary uses the file pointer as a key (with one entry
2834 * inserted for each file returned by the original popen* call) and a
2835 * single list object as the value for all files from a single call.
2836 * The list object contains the Win32 process handle at [0], and a file
2837 * count at [1], which is initialized to the total number of file
2838 * handles using that list.
2839 *
2840 * This function closes whichever handle it is passed, and decrements
2841 * the file count in the dictionary for the process handle pointed to
2842 * by this file. On the last close (when the file count reaches zero),
2843 * this function will wait for the child process and then return its
2844 * exit code as the result of the close() operation. This permits the
2845 * files to be closed in any order - it is always the close() of the
2846 * final handle that will return the exit code.
2847 */
2848
2849 /* RED_FLAG 31-Aug-2000 Tim
2850 * This is always called (today!) between a pair of
2851 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2852 * macros. So the thread running this has no valid thread state, as
2853 * far as Python is concerned. However, this calls some Python API
2854 * functions that cannot be called safely without a valid thread
2855 * state, in particular PyDict_GetItem.
2856 * As a temporary hack (although it may last for years ...), we
2857 * *rely* on not having a valid thread state in this function, in
2858 * order to create our own "from scratch".
2859 * This will deadlock if _PyPclose is ever called by a thread
2860 * holding the global lock.
2861 * (The OS/2 EMX thread support appears to cover the case where the
2862 * lock is already held - AIM Apr01)
2863 */
2864
2865static int _PyPclose(FILE *file)
2866{
2867 int result;
2868 int exit_code;
2869 int pipe_pid;
2870 PyObject *procObj, *pidObj, *intObj, *fileObj;
2871 int file_count;
2872#ifdef WITH_THREAD
2873 PyInterpreterState* pInterpreterState;
2874 PyThreadState* pThreadState;
2875#endif
2876
2877 /* Close the file handle first, to ensure it can't block the
2878 * child from exiting if it's the last handle.
2879 */
2880 result = fclose(file);
2881
2882#ifdef WITH_THREAD
2883 /* Bootstrap a valid thread state into existence. */
2884 pInterpreterState = PyInterpreterState_New();
2885 if (!pInterpreterState) {
2886 /* Well, we're hosed now! We don't have a thread
2887 * state, so can't call a nice error routine, or raise
2888 * an exception. Just die.
2889 */
2890 Py_FatalError("unable to allocate interpreter state "
2891 "when closing popen object.");
2892 return -1; /* unreachable */
2893 }
2894 pThreadState = PyThreadState_New(pInterpreterState);
2895 if (!pThreadState) {
2896 Py_FatalError("unable to allocate thread state "
2897 "when closing popen object.");
2898 return -1; /* unreachable */
2899 }
2900 /* Grab the global lock. Note that this will deadlock if the
2901 * current thread already has the lock! (see RED_FLAG comments
2902 * before this function)
2903 */
2904 PyEval_RestoreThread(pThreadState);
2905#endif
2906
2907 if (_PyPopenProcs)
2908 {
2909 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2910 (procObj = PyDict_GetItem(_PyPopenProcs,
2911 fileObj)) != NULL &&
2912 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2913 (intObj = PyList_GetItem(procObj,1)) != NULL)
2914 {
2915 pipe_pid = (int) PyInt_AsLong(pidObj);
2916 file_count = (int) PyInt_AsLong(intObj);
2917
2918 if (file_count > 1)
2919 {
2920 /* Still other files referencing process */
2921 file_count--;
2922 PyList_SetItem(procObj,1,
2923 PyInt_FromLong((long) file_count));
2924 }
2925 else
2926 {
2927 /* Last file for this process */
2928 if (result != EOF &&
2929 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2930 {
2931 /* extract exit status */
2932 if (WIFEXITED(exit_code))
2933 {
2934 result = WEXITSTATUS(exit_code);
2935 }
2936 else
2937 {
2938 errno = EPIPE;
2939 result = -1;
2940 }
2941 }
2942 else
2943 {
2944 /* Indicate failure - this will cause the file object
2945 * to raise an I/O error and translate the last
2946 * error code from errno. We do have a problem with
2947 * last errors that overlap the normal errno table,
2948 * but that's a consistent problem with the file object.
2949 */
2950 result = -1;
2951 }
2952 }
2953
2954 /* Remove this file pointer from dictionary */
2955 PyDict_DelItem(_PyPopenProcs, fileObj);
2956
2957 if (PyDict_Size(_PyPopenProcs) == 0)
2958 {
2959 Py_DECREF(_PyPopenProcs);
2960 _PyPopenProcs = NULL;
2961 }
2962
2963 } /* if object retrieval ok */
2964
2965 Py_XDECREF(fileObj);
2966 } /* if _PyPopenProcs */
2967
2968#ifdef WITH_THREAD
2969 /* Tear down the thread & interpreter states.
2970 * Note that interpreter state clear & delete functions automatically
2971 * call the thread clear & delete functions, and indeed insist on
2972 * doing that themselves. The lock must be held during the clear, but
2973 * need not be held during the delete.
2974 */
2975 PyInterpreterState_Clear(pInterpreterState);
2976 PyEval_ReleaseThread(pThreadState);
2977 PyInterpreterState_Delete(pInterpreterState);
2978#endif
2979
2980 return result;
2981}
2982
2983#endif /* PYCC_??? */
2984
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002985#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002986
2987/*
2988 * Portable 'popen' replacement for Win32.
2989 *
2990 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2991 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002992 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002993 */
2994
2995#include <malloc.h>
2996#include <io.h>
2997#include <fcntl.h>
2998
2999/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3000#define POPEN_1 1
3001#define POPEN_2 2
3002#define POPEN_3 3
3003#define POPEN_4 4
3004
3005static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003006static int _PyPclose(FILE *file);
3007
3008/*
3009 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003010 * for use when retrieving the process exit code. See _PyPclose() below
3011 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003012 */
3013static PyObject *_PyPopenProcs = NULL;
3014
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003015
3016/* popen that works from a GUI.
3017 *
3018 * The result of this function is a pipe (file) connected to the
3019 * processes stdin or stdout, depending on the requested mode.
3020 */
3021
3022static PyObject *
3023posix_popen(PyObject *self, PyObject *args)
3024{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003025 PyObject *f, *s;
3026 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003027
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003028 char *cmdstring;
3029 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003030 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003031 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003032 return NULL;
3033
3034 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003035
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003036 if (*mode == 'r')
3037 tm = _O_RDONLY;
3038 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003039 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003040 return NULL;
3041 } else
3042 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003043
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003044 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003045 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003046 return NULL;
3047 }
3048
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003049 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003050 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003051 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003052 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003053 else
3054 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3055
3056 return f;
3057}
3058
3059/* Variation on win32pipe.popen
3060 *
3061 * The result of this function is a pipe (file) connected to the
3062 * process's stdin, and a pipe connected to the process's stdout.
3063 */
3064
3065static PyObject *
3066win32_popen2(PyObject *self, PyObject *args)
3067{
3068 PyObject *f;
3069 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003070
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003071 char *cmdstring;
3072 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003073 int bufsize = -1;
3074 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003075 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003076
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003077 if (*mode == 't')
3078 tm = _O_TEXT;
3079 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003080 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003081 return NULL;
3082 } else
3083 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003084
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003085 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003086 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003087 return NULL;
3088 }
3089
3090 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003091
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003092 return f;
3093}
3094
3095/*
3096 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003097 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003098 * The result of this function is 3 pipes - the process's stdin,
3099 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003100 */
3101
3102static PyObject *
3103win32_popen3(PyObject *self, PyObject *args)
3104{
3105 PyObject *f;
3106 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003107
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003108 char *cmdstring;
3109 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003110 int bufsize = -1;
3111 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003112 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003113
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003114 if (*mode == 't')
3115 tm = _O_TEXT;
3116 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003117 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003118 return NULL;
3119 } else
3120 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003121
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003122 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003123 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003124 return NULL;
3125 }
3126
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003127 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003128
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003129 return f;
3130}
3131
3132/*
3133 * Variation on win32pipe.popen
3134 *
Tim Peters5aa91602002-01-30 05:46:57 +00003135 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003136 * and stdout+stderr combined as a single pipe.
3137 */
3138
3139static PyObject *
3140win32_popen4(PyObject *self, PyObject *args)
3141{
3142 PyObject *f;
3143 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003144
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003145 char *cmdstring;
3146 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003147 int bufsize = -1;
3148 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003149 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003150
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003151 if (*mode == 't')
3152 tm = _O_TEXT;
3153 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003154 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003155 return NULL;
3156 } else
3157 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003158
3159 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003160 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003161 return NULL;
3162 }
3163
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003164 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003165
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003166 return f;
3167}
3168
Mark Hammond08501372001-01-31 07:30:29 +00003169static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003170_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003171 HANDLE hStdin,
3172 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003173 HANDLE hStderr,
3174 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003175{
3176 PROCESS_INFORMATION piProcInfo;
3177 STARTUPINFO siStartInfo;
3178 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003179 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003180 int i;
3181 int x;
3182
3183 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003184 char *comshell;
3185
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003186 s1 = (char *)_alloca(i);
3187 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3188 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003189
3190 /* Explicitly check if we are using COMMAND.COM. If we are
3191 * then use the w9xpopen hack.
3192 */
3193 comshell = s1 + x;
3194 while (comshell >= s1 && *comshell != '\\')
3195 --comshell;
3196 ++comshell;
3197
3198 if (GetVersion() < 0x80000000 &&
3199 _stricmp(comshell, "command.com") != 0) {
3200 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003201 x = i + strlen(s3) + strlen(cmdstring) + 1;
3202 s2 = (char *)_alloca(x);
3203 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003204 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003205 }
3206 else {
3207 /*
Tim Peters402d5982001-08-27 06:37:48 +00003208 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3209 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003210 */
Mark Hammond08501372001-01-31 07:30:29 +00003211 char modulepath[_MAX_PATH];
3212 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003213 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3214 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003215 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003216 x = i+1;
3217 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003218 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003219 strncat(modulepath,
3220 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003221 (sizeof(modulepath)/sizeof(modulepath[0]))
3222 -strlen(modulepath));
3223 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003224 /* Eeek - file-not-found - possibly an embedding
3225 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003226 */
Tim Peters5aa91602002-01-30 05:46:57 +00003227 strncpy(modulepath,
3228 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003229 sizeof(modulepath)/sizeof(modulepath[0]));
3230 if (modulepath[strlen(modulepath)-1] != '\\')
3231 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003232 strncat(modulepath,
3233 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003234 (sizeof(modulepath)/sizeof(modulepath[0]))
3235 -strlen(modulepath));
3236 /* No where else to look - raise an easily identifiable
3237 error, rather than leaving Windows to report
3238 "file not found" - as the user is probably blissfully
3239 unaware this shim EXE is used, and it will confuse them.
3240 (well, it confused me for a while ;-)
3241 */
3242 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003243 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003244 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003245 "for popen to work with your shell "
3246 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003247 szConsoleSpawn);
3248 return FALSE;
3249 }
3250 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003251 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003252 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003253 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003254
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003255 s2 = (char *)_alloca(x);
3256 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003257 /* To maintain correct argument passing semantics,
3258 we pass the command-line as it stands, and allow
3259 quoting to be applied. w9xpopen.exe will then
3260 use its argv vector, and re-quote the necessary
3261 args for the ultimate child process.
3262 */
Tim Peters75cdad52001-11-28 22:07:30 +00003263 PyOS_snprintf(
3264 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003265 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003266 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003267 s1,
3268 s3,
3269 cmdstring);
3270 }
3271 }
3272
3273 /* Could be an else here to try cmd.exe / command.com in the path
3274 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003275 else {
Tim Peters402d5982001-08-27 06:37:48 +00003276 PyErr_SetString(PyExc_RuntimeError,
3277 "Cannot locate a COMSPEC environment variable to "
3278 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003279 return FALSE;
3280 }
Tim Peters5aa91602002-01-30 05:46:57 +00003281
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003282 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3283 siStartInfo.cb = sizeof(STARTUPINFO);
3284 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3285 siStartInfo.hStdInput = hStdin;
3286 siStartInfo.hStdOutput = hStdout;
3287 siStartInfo.hStdError = hStderr;
3288 siStartInfo.wShowWindow = SW_HIDE;
3289
3290 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003291 s2,
3292 NULL,
3293 NULL,
3294 TRUE,
Mark Hammond155adbd2002-07-14 23:28:16 +00003295 0, /* no new console so Ctrl+C kills child too */
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003296 NULL,
3297 NULL,
3298 &siStartInfo,
3299 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003300 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003301 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003302
Mark Hammondb37a3732000-08-14 04:47:33 +00003303 /* Return process handle */
3304 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003305 return TRUE;
3306 }
Tim Peters402d5982001-08-27 06:37:48 +00003307 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003308 return FALSE;
3309}
3310
3311/* The following code is based off of KB: Q190351 */
3312
3313static PyObject *
3314_PyPopen(char *cmdstring, int mode, int n)
3315{
3316 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3317 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003318 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003319
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003320 SECURITY_ATTRIBUTES saAttr;
3321 BOOL fSuccess;
3322 int fd1, fd2, fd3;
3323 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003324 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003325 PyObject *f;
3326
3327 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3328 saAttr.bInheritHandle = TRUE;
3329 saAttr.lpSecurityDescriptor = NULL;
3330
3331 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3332 return win32_error("CreatePipe", NULL);
3333
3334 /* Create new output read handle and the input write handle. Set
3335 * the inheritance properties to FALSE. Otherwise, the child inherits
3336 * the these handles; resulting in non-closeable handles to the pipes
3337 * being created. */
3338 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003339 GetCurrentProcess(), &hChildStdinWrDup, 0,
3340 FALSE,
3341 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003342 if (!fSuccess)
3343 return win32_error("DuplicateHandle", NULL);
3344
3345 /* Close the inheritable version of ChildStdin
3346 that we're using. */
3347 CloseHandle(hChildStdinWr);
3348
3349 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3350 return win32_error("CreatePipe", NULL);
3351
3352 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003353 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3354 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003355 if (!fSuccess)
3356 return win32_error("DuplicateHandle", NULL);
3357
3358 /* Close the inheritable version of ChildStdout
3359 that we're using. */
3360 CloseHandle(hChildStdoutRd);
3361
3362 if (n != POPEN_4) {
3363 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3364 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003365 fSuccess = DuplicateHandle(GetCurrentProcess(),
3366 hChildStderrRd,
3367 GetCurrentProcess(),
3368 &hChildStderrRdDup, 0,
3369 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003370 if (!fSuccess)
3371 return win32_error("DuplicateHandle", NULL);
3372 /* Close the inheritable version of ChildStdErr that we're using. */
3373 CloseHandle(hChildStderrRd);
3374 }
Tim Peters5aa91602002-01-30 05:46:57 +00003375
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003376 switch (n) {
3377 case POPEN_1:
3378 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3379 case _O_WRONLY | _O_TEXT:
3380 /* Case for writing to child Stdin in text mode. */
3381 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3382 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003383 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003384 PyFile_SetBufSize(f, 0);
3385 /* We don't care about these pipes anymore, so close them. */
3386 CloseHandle(hChildStdoutRdDup);
3387 CloseHandle(hChildStderrRdDup);
3388 break;
3389
3390 case _O_RDONLY | _O_TEXT:
3391 /* Case for reading from child Stdout in text mode. */
3392 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3393 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003394 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003395 PyFile_SetBufSize(f, 0);
3396 /* We don't care about these pipes anymore, so close them. */
3397 CloseHandle(hChildStdinWrDup);
3398 CloseHandle(hChildStderrRdDup);
3399 break;
3400
3401 case _O_RDONLY | _O_BINARY:
3402 /* Case for readinig from child Stdout in binary mode. */
3403 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3404 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003405 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003406 PyFile_SetBufSize(f, 0);
3407 /* We don't care about these pipes anymore, so close them. */
3408 CloseHandle(hChildStdinWrDup);
3409 CloseHandle(hChildStderrRdDup);
3410 break;
3411
3412 case _O_WRONLY | _O_BINARY:
3413 /* Case for writing to child Stdin in binary mode. */
3414 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3415 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003416 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003417 PyFile_SetBufSize(f, 0);
3418 /* We don't care about these pipes anymore, so close them. */
3419 CloseHandle(hChildStdoutRdDup);
3420 CloseHandle(hChildStderrRdDup);
3421 break;
3422 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003423 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003424 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003425
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003426 case POPEN_2:
3427 case POPEN_4:
3428 {
3429 char *m1, *m2;
3430 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003431
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003432 if (mode && _O_TEXT) {
3433 m1 = "r";
3434 m2 = "w";
3435 } else {
3436 m1 = "rb";
3437 m2 = "wb";
3438 }
3439
3440 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3441 f1 = _fdopen(fd1, m2);
3442 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3443 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003444 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003445 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003446 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003447 PyFile_SetBufSize(p2, 0);
3448
3449 if (n != 4)
3450 CloseHandle(hChildStderrRdDup);
3451
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003452 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003453 Py_XDECREF(p1);
3454 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003455 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003456 break;
3457 }
Tim Peters5aa91602002-01-30 05:46:57 +00003458
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003459 case POPEN_3:
3460 {
3461 char *m1, *m2;
3462 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003463
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003464 if (mode && _O_TEXT) {
3465 m1 = "r";
3466 m2 = "w";
3467 } else {
3468 m1 = "rb";
3469 m2 = "wb";
3470 }
3471
3472 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3473 f1 = _fdopen(fd1, m2);
3474 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3475 f2 = _fdopen(fd2, m1);
3476 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3477 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003478 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003479 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3480 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003481 PyFile_SetBufSize(p1, 0);
3482 PyFile_SetBufSize(p2, 0);
3483 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003484 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003485 Py_XDECREF(p1);
3486 Py_XDECREF(p2);
3487 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003488 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003489 break;
3490 }
3491 }
3492
3493 if (n == POPEN_4) {
3494 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003495 hChildStdinRd,
3496 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003497 hChildStdoutWr,
3498 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003499 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003500 }
3501 else {
3502 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003503 hChildStdinRd,
3504 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003505 hChildStderrWr,
3506 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003507 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003508 }
3509
Mark Hammondb37a3732000-08-14 04:47:33 +00003510 /*
3511 * Insert the files we've created into the process dictionary
3512 * all referencing the list with the process handle and the
3513 * initial number of files (see description below in _PyPclose).
3514 * Since if _PyPclose later tried to wait on a process when all
3515 * handles weren't closed, it could create a deadlock with the
3516 * child, we spend some energy here to try to ensure that we
3517 * either insert all file handles into the dictionary or none
3518 * at all. It's a little clumsy with the various popen modes
3519 * and variable number of files involved.
3520 */
3521 if (!_PyPopenProcs) {
3522 _PyPopenProcs = PyDict_New();
3523 }
3524
3525 if (_PyPopenProcs) {
3526 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3527 int ins_rc[3];
3528
3529 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3530 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3531
3532 procObj = PyList_New(2);
3533 hProcessObj = PyLong_FromVoidPtr(hProcess);
3534 intObj = PyInt_FromLong(file_count);
3535
3536 if (procObj && hProcessObj && intObj) {
3537 PyList_SetItem(procObj,0,hProcessObj);
3538 PyList_SetItem(procObj,1,intObj);
3539
3540 fileObj[0] = PyLong_FromVoidPtr(f1);
3541 if (fileObj[0]) {
3542 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3543 fileObj[0],
3544 procObj);
3545 }
3546 if (file_count >= 2) {
3547 fileObj[1] = PyLong_FromVoidPtr(f2);
3548 if (fileObj[1]) {
3549 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3550 fileObj[1],
3551 procObj);
3552 }
3553 }
3554 if (file_count >= 3) {
3555 fileObj[2] = PyLong_FromVoidPtr(f3);
3556 if (fileObj[2]) {
3557 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3558 fileObj[2],
3559 procObj);
3560 }
3561 }
3562
3563 if (ins_rc[0] < 0 || !fileObj[0] ||
3564 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3565 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3566 /* Something failed - remove any dictionary
3567 * entries that did make it.
3568 */
3569 if (!ins_rc[0] && fileObj[0]) {
3570 PyDict_DelItem(_PyPopenProcs,
3571 fileObj[0]);
3572 }
3573 if (!ins_rc[1] && fileObj[1]) {
3574 PyDict_DelItem(_PyPopenProcs,
3575 fileObj[1]);
3576 }
3577 if (!ins_rc[2] && fileObj[2]) {
3578 PyDict_DelItem(_PyPopenProcs,
3579 fileObj[2]);
3580 }
3581 }
3582 }
Tim Peters5aa91602002-01-30 05:46:57 +00003583
Mark Hammondb37a3732000-08-14 04:47:33 +00003584 /*
3585 * Clean up our localized references for the dictionary keys
3586 * and value since PyDict_SetItem will Py_INCREF any copies
3587 * that got placed in the dictionary.
3588 */
3589 Py_XDECREF(procObj);
3590 Py_XDECREF(fileObj[0]);
3591 Py_XDECREF(fileObj[1]);
3592 Py_XDECREF(fileObj[2]);
3593 }
3594
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003595 /* Child is launched. Close the parents copy of those pipe
3596 * handles that only the child should have open. You need to
3597 * make sure that no handles to the write end of the output pipe
3598 * are maintained in this process or else the pipe will not close
3599 * when the child process exits and the ReadFile will hang. */
3600
3601 if (!CloseHandle(hChildStdinRd))
3602 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003603
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003604 if (!CloseHandle(hChildStdoutWr))
3605 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003606
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003607 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3608 return win32_error("CloseHandle", NULL);
3609
3610 return f;
3611}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003612
3613/*
3614 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3615 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003616 *
3617 * This function uses the _PyPopenProcs dictionary in order to map the
3618 * input file pointer to information about the process that was
3619 * originally created by the popen* call that created the file pointer.
3620 * The dictionary uses the file pointer as a key (with one entry
3621 * inserted for each file returned by the original popen* call) and a
3622 * single list object as the value for all files from a single call.
3623 * The list object contains the Win32 process handle at [0], and a file
3624 * count at [1], which is initialized to the total number of file
3625 * handles using that list.
3626 *
3627 * This function closes whichever handle it is passed, and decrements
3628 * the file count in the dictionary for the process handle pointed to
3629 * by this file. On the last close (when the file count reaches zero),
3630 * this function will wait for the child process and then return its
3631 * exit code as the result of the close() operation. This permits the
3632 * files to be closed in any order - it is always the close() of the
3633 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003634 */
Tim Peters736aa322000-09-01 06:51:24 +00003635
3636 /* RED_FLAG 31-Aug-2000 Tim
3637 * This is always called (today!) between a pair of
3638 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3639 * macros. So the thread running this has no valid thread state, as
3640 * far as Python is concerned. However, this calls some Python API
3641 * functions that cannot be called safely without a valid thread
3642 * state, in particular PyDict_GetItem.
3643 * As a temporary hack (although it may last for years ...), we
3644 * *rely* on not having a valid thread state in this function, in
3645 * order to create our own "from scratch".
3646 * This will deadlock if _PyPclose is ever called by a thread
3647 * holding the global lock.
3648 */
3649
Fredrik Lundh56055a42000-07-23 19:47:12 +00003650static int _PyPclose(FILE *file)
3651{
Fredrik Lundh20318932000-07-26 17:29:12 +00003652 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003653 DWORD exit_code;
3654 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003655 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3656 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003657#ifdef WITH_THREAD
3658 PyInterpreterState* pInterpreterState;
3659 PyThreadState* pThreadState;
3660#endif
3661
Fredrik Lundh20318932000-07-26 17:29:12 +00003662 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003663 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003664 */
3665 result = fclose(file);
3666
Tim Peters736aa322000-09-01 06:51:24 +00003667#ifdef WITH_THREAD
3668 /* Bootstrap a valid thread state into existence. */
3669 pInterpreterState = PyInterpreterState_New();
3670 if (!pInterpreterState) {
3671 /* Well, we're hosed now! We don't have a thread
3672 * state, so can't call a nice error routine, or raise
3673 * an exception. Just die.
3674 */
3675 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003676 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003677 return -1; /* unreachable */
3678 }
3679 pThreadState = PyThreadState_New(pInterpreterState);
3680 if (!pThreadState) {
3681 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003682 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003683 return -1; /* unreachable */
3684 }
3685 /* Grab the global lock. Note that this will deadlock if the
3686 * current thread already has the lock! (see RED_FLAG comments
3687 * before this function)
3688 */
3689 PyEval_RestoreThread(pThreadState);
3690#endif
3691
Fredrik Lundh56055a42000-07-23 19:47:12 +00003692 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003693 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3694 (procObj = PyDict_GetItem(_PyPopenProcs,
3695 fileObj)) != NULL &&
3696 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3697 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3698
3699 hProcess = PyLong_AsVoidPtr(hProcessObj);
3700 file_count = PyInt_AsLong(intObj);
3701
3702 if (file_count > 1) {
3703 /* Still other files referencing process */
3704 file_count--;
3705 PyList_SetItem(procObj,1,
3706 PyInt_FromLong(file_count));
3707 } else {
3708 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003709 if (result != EOF &&
3710 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3711 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003712 /* Possible truncation here in 16-bit environments, but
3713 * real exit codes are just the lower byte in any event.
3714 */
3715 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003716 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003717 /* Indicate failure - this will cause the file object
3718 * to raise an I/O error and translate the last Win32
3719 * error code from errno. We do have a problem with
3720 * last errors that overlap the normal errno table,
3721 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003722 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003723 if (result != EOF) {
3724 /* If the error wasn't from the fclose(), then
3725 * set errno for the file object error handling.
3726 */
3727 errno = GetLastError();
3728 }
3729 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003730 }
3731
3732 /* Free up the native handle at this point */
3733 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003734 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003735
Mark Hammondb37a3732000-08-14 04:47:33 +00003736 /* Remove this file pointer from dictionary */
3737 PyDict_DelItem(_PyPopenProcs, fileObj);
3738
3739 if (PyDict_Size(_PyPopenProcs) == 0) {
3740 Py_DECREF(_PyPopenProcs);
3741 _PyPopenProcs = NULL;
3742 }
3743
3744 } /* if object retrieval ok */
3745
3746 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003747 } /* if _PyPopenProcs */
3748
Tim Peters736aa322000-09-01 06:51:24 +00003749#ifdef WITH_THREAD
3750 /* Tear down the thread & interpreter states.
3751 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003752 * call the thread clear & delete functions, and indeed insist on
3753 * doing that themselves. The lock must be held during the clear, but
3754 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003755 */
3756 PyInterpreterState_Clear(pInterpreterState);
3757 PyEval_ReleaseThread(pThreadState);
3758 PyInterpreterState_Delete(pInterpreterState);
3759#endif
3760
Fredrik Lundh56055a42000-07-23 19:47:12 +00003761 return result;
3762}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003763
3764#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003766posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003767{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003768 char *name;
3769 char *mode = "r";
3770 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003771 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003772 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003773 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003774 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003775 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003776 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003777 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003778 if (fp == NULL)
3779 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003780 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003781 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003782 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003783 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003784}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003785
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003786#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003787#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003788
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003789
Guido van Rossumb6775db1994-08-01 11:34:53 +00003790#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003791PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003792"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003793Set the current process's user id.");
3794
Barry Warsaw53699e91996-12-10 23:23:01 +00003795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003796posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003797{
3798 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003799 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003800 return NULL;
3801 if (setuid(uid) < 0)
3802 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003803 Py_INCREF(Py_None);
3804 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003805}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003806#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003808
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003809#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003810PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003811"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003812Set the current process's effective user id.");
3813
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003814static PyObject *
3815posix_seteuid (PyObject *self, PyObject *args)
3816{
3817 int euid;
3818 if (!PyArg_ParseTuple(args, "i", &euid)) {
3819 return NULL;
3820 } else if (seteuid(euid) < 0) {
3821 return posix_error();
3822 } else {
3823 Py_INCREF(Py_None);
3824 return Py_None;
3825 }
3826}
3827#endif /* HAVE_SETEUID */
3828
3829#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003830PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003831"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003832Set the current process's effective group id.");
3833
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003834static PyObject *
3835posix_setegid (PyObject *self, PyObject *args)
3836{
3837 int egid;
3838 if (!PyArg_ParseTuple(args, "i", &egid)) {
3839 return NULL;
3840 } else if (setegid(egid) < 0) {
3841 return posix_error();
3842 } else {
3843 Py_INCREF(Py_None);
3844 return Py_None;
3845 }
3846}
3847#endif /* HAVE_SETEGID */
3848
3849#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003850PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003851"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003852Set the current process's real and effective user ids.");
3853
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003854static PyObject *
3855posix_setreuid (PyObject *self, PyObject *args)
3856{
3857 int ruid, euid;
3858 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3859 return NULL;
3860 } else if (setreuid(ruid, euid) < 0) {
3861 return posix_error();
3862 } else {
3863 Py_INCREF(Py_None);
3864 return Py_None;
3865 }
3866}
3867#endif /* HAVE_SETREUID */
3868
3869#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003870PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003871"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003872Set the current process's real and effective group ids.");
3873
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003874static PyObject *
3875posix_setregid (PyObject *self, PyObject *args)
3876{
3877 int rgid, egid;
3878 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3879 return NULL;
3880 } else if (setregid(rgid, egid) < 0) {
3881 return posix_error();
3882 } else {
3883 Py_INCREF(Py_None);
3884 return Py_None;
3885 }
3886}
3887#endif /* HAVE_SETREGID */
3888
Guido van Rossumb6775db1994-08-01 11:34:53 +00003889#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003890PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003891"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003892Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003893
Barry Warsaw53699e91996-12-10 23:23:01 +00003894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003895posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003896{
3897 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003898 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003899 return NULL;
3900 if (setgid(gid) < 0)
3901 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003902 Py_INCREF(Py_None);
3903 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003904}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003905#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003906
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003907#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003908PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003909"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003910Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003911
3912static PyObject *
3913posix_setgroups(PyObject *self, PyObject *args)
3914{
3915 PyObject *groups;
3916 int i, len;
3917 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003918
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003919 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3920 return NULL;
3921 if (!PySequence_Check(groups)) {
3922 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3923 return NULL;
3924 }
3925 len = PySequence_Size(groups);
3926 if (len > MAX_GROUPS) {
3927 PyErr_SetString(PyExc_ValueError, "too many groups");
3928 return NULL;
3929 }
3930 for(i = 0; i < len; i++) {
3931 PyObject *elem;
3932 elem = PySequence_GetItem(groups, i);
3933 if (!elem)
3934 return NULL;
3935 if (!PyInt_Check(elem)) {
3936 PyErr_SetString(PyExc_TypeError,
3937 "groups must be integers");
3938 Py_DECREF(elem);
3939 return NULL;
3940 }
3941 /* XXX: check that value fits into gid_t. */
3942 grouplist[i] = PyInt_AsLong(elem);
3943 Py_DECREF(elem);
3944 }
3945
3946 if (setgroups(len, grouplist) < 0)
3947 return posix_error();
3948 Py_INCREF(Py_None);
3949 return Py_None;
3950}
3951#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003952
Guido van Rossumb6775db1994-08-01 11:34:53 +00003953#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003954PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003955"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003956Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003957
Barry Warsaw53699e91996-12-10 23:23:01 +00003958static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003959posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003960{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003961 int pid, options;
3962#ifdef UNION_WAIT
3963 union wait status;
3964#define status_i (status.w_status)
3965#else
3966 int status;
3967#define status_i status
3968#endif
3969 status_i = 0;
3970
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003971 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003972 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003973 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003974 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00003975 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003976 if (pid == -1)
3977 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003978 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003979 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003980}
3981
Tim Petersab034fa2002-02-01 11:27:43 +00003982#elif defined(HAVE_CWAIT)
3983
3984/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003985PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003986"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003987"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00003988
3989static PyObject *
3990posix_waitpid(PyObject *self, PyObject *args)
3991{
3992 int pid, options;
3993 int status;
3994
3995 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
3996 return NULL;
3997 Py_BEGIN_ALLOW_THREADS
3998 pid = _cwait(&status, pid, options);
3999 Py_END_ALLOW_THREADS
4000 if (pid == -1)
4001 return posix_error();
4002 else
4003 /* shift the status left a byte so this is more like the
4004 POSIX waitpid */
4005 return Py_BuildValue("ii", pid, status << 8);
4006}
4007#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004008
Guido van Rossumad0ee831995-03-01 10:34:45 +00004009#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004010PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004011"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004012Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004013
Barry Warsaw53699e91996-12-10 23:23:01 +00004014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004015posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004016{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004017 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004018#ifdef UNION_WAIT
4019 union wait status;
4020#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004021#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004022 int status;
4023#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004024#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004025 if (!PyArg_ParseTuple(args, ":wait"))
4026 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004027 status_i = 0;
4028 Py_BEGIN_ALLOW_THREADS
4029 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004030 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004031 if (pid == -1)
4032 return posix_error();
4033 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004034 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004035#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004036}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004037#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004039
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004040PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004041"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004042Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004043
Barry Warsaw53699e91996-12-10 23:23:01 +00004044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004045posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004046{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004047#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004048 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004049#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004050 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004051#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004052}
4053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004054
Guido van Rossumb6775db1994-08-01 11:34:53 +00004055#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004056PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004057"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004058Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004059
Barry Warsaw53699e91996-12-10 23:23:01 +00004060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004061posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004062{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004063 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004064 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004065 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004066 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004067 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004068 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004069 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004070 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004071 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004072 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004073 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004074}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004075#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004077
Guido van Rossumb6775db1994-08-01 11:34:53 +00004078#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004079PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004080"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004081Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004082
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004084posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004085{
Mark Hammondef8b6542001-05-13 08:04:26 +00004086 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004087}
4088#endif /* HAVE_SYMLINK */
4089
4090
4091#ifdef HAVE_TIMES
4092#ifndef HZ
4093#define HZ 60 /* Universal constant :-) */
4094#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004095
Guido van Rossumd48f2521997-12-05 22:19:34 +00004096#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4097static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004098system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004099{
4100 ULONG value = 0;
4101
4102 Py_BEGIN_ALLOW_THREADS
4103 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4104 Py_END_ALLOW_THREADS
4105
4106 return value;
4107}
4108
4109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004110posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004111{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004112 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004113 return NULL;
4114
4115 /* Currently Only Uptime is Provided -- Others Later */
4116 return Py_BuildValue("ddddd",
4117 (double)0 /* t.tms_utime / HZ */,
4118 (double)0 /* t.tms_stime / HZ */,
4119 (double)0 /* t.tms_cutime / HZ */,
4120 (double)0 /* t.tms_cstime / HZ */,
4121 (double)system_uptime() / 1000);
4122}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004123#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004125posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004126{
4127 struct tms t;
4128 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004129 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004130 return NULL;
4131 errno = 0;
4132 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004133 if (c == (clock_t) -1)
4134 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004135 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004136 (double)t.tms_utime / HZ,
4137 (double)t.tms_stime / HZ,
4138 (double)t.tms_cutime / HZ,
4139 (double)t.tms_cstime / HZ,
4140 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004141}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004142#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004143#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004144
4145
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004146#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004147#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004148static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004149posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004150{
4151 FILETIME create, exit, kernel, user;
4152 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004153 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004154 return NULL;
4155 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004156 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4157 /* The fields of a FILETIME structure are the hi and lo part
4158 of a 64-bit value expressed in 100 nanosecond units.
4159 1e7 is one second in such units; 1e-7 the inverse.
4160 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4161 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004162 return Py_BuildValue(
4163 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004164 (double)(kernel.dwHighDateTime*429.4967296 +
4165 kernel.dwLowDateTime*1e-7),
4166 (double)(user.dwHighDateTime*429.4967296 +
4167 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004168 (double)0,
4169 (double)0,
4170 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004171}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004172#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004173
4174#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004175PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004176"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004177Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004178#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004179
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004180
Guido van Rossumb6775db1994-08-01 11:34:53 +00004181#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004182PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004183"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004184Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004185
Barry Warsaw53699e91996-12-10 23:23:01 +00004186static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004187posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004188{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004189 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004190 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004191 if (setsid() < 0)
4192 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004193 Py_INCREF(Py_None);
4194 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004195}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004196#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004197
Guido van Rossumb6775db1994-08-01 11:34:53 +00004198#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004199PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004200"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004201Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004202
Barry Warsaw53699e91996-12-10 23:23:01 +00004203static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004204posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004205{
4206 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004207 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004208 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004209 if (setpgid(pid, pgrp) < 0)
4210 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004211 Py_INCREF(Py_None);
4212 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004213}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004214#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004216
Guido van Rossumb6775db1994-08-01 11:34:53 +00004217#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004218PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004219"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004220Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004221
Barry Warsaw53699e91996-12-10 23:23:01 +00004222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004223posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004224{
4225 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004226 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004227 return NULL;
4228 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004229 if (pgid < 0)
4230 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004231 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004232}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004233#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004234
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004235
Guido van Rossumb6775db1994-08-01 11:34:53 +00004236#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004237PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004238"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004239Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004240
Barry Warsaw53699e91996-12-10 23:23:01 +00004241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004242posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004243{
4244 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004245 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004246 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004247 if (tcsetpgrp(fd, pgid) < 0)
4248 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004249 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004250 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004251}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004252#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004253
Guido van Rossum687dd131993-05-17 08:34:16 +00004254/* Functions acting on file descriptors */
4255
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004256PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004257"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004258Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004259
Barry Warsaw53699e91996-12-10 23:23:01 +00004260static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004261posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004262{
Mark Hammondef8b6542001-05-13 08:04:26 +00004263 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004264 int flag;
4265 int mode = 0777;
4266 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004267 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004268 Py_FileSystemDefaultEncoding, &file,
4269 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004270 return NULL;
4271
Barry Warsaw53699e91996-12-10 23:23:01 +00004272 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004273 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004274 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004275 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004276 return posix_error_with_allocated_filename(file);
4277 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004278 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004279}
4280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004281
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004282PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004283"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004284Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004285
Barry Warsaw53699e91996-12-10 23:23:01 +00004286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004287posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004288{
4289 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004290 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004291 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004292 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004293 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004294 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004295 if (res < 0)
4296 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004297 Py_INCREF(Py_None);
4298 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004299}
4300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004302PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004303"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004304Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004305
Barry Warsaw53699e91996-12-10 23:23:01 +00004306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004307posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004308{
4309 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004310 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004311 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004312 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004313 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004314 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004315 if (fd < 0)
4316 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004317 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004318}
4319
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004320
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004321PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004322"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004323Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004324
Barry Warsaw53699e91996-12-10 23:23:01 +00004325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004326posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004327{
4328 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004329 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004330 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004331 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004332 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004333 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004334 if (res < 0)
4335 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004336 Py_INCREF(Py_None);
4337 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004338}
4339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004340
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004341PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004342"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004343Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004344
Barry Warsaw53699e91996-12-10 23:23:01 +00004345static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004346posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004347{
4348 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004349#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004350 LONG_LONG pos, res;
4351#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004352 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004353#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004354 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004355 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004356 return NULL;
4357#ifdef SEEK_SET
4358 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4359 switch (how) {
4360 case 0: how = SEEK_SET; break;
4361 case 1: how = SEEK_CUR; break;
4362 case 2: how = SEEK_END; break;
4363 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004364#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004365
4366#if !defined(HAVE_LARGEFILE_SUPPORT)
4367 pos = PyInt_AsLong(posobj);
4368#else
4369 pos = PyLong_Check(posobj) ?
4370 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4371#endif
4372 if (PyErr_Occurred())
4373 return NULL;
4374
Barry Warsaw53699e91996-12-10 23:23:01 +00004375 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004376#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004377 res = _lseeki64(fd, pos, how);
4378#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004379 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004380#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004381 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004382 if (res < 0)
4383 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004384
4385#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004386 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004387#else
4388 return PyLong_FromLongLong(res);
4389#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004390}
4391
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004392
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004393PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004394"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004395Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004396
Barry Warsaw53699e91996-12-10 23:23:01 +00004397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004398posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004399{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004400 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004401 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004402 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004403 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004404 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004405 if (buffer == NULL)
4406 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004407 Py_BEGIN_ALLOW_THREADS
4408 n = read(fd, PyString_AsString(buffer), size);
4409 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004410 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004411 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004412 return posix_error();
4413 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004414 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004415 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004416 return buffer;
4417}
4418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004419
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004420PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004421"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004422Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004423
Barry Warsaw53699e91996-12-10 23:23:01 +00004424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004425posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004426{
4427 int fd, size;
4428 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004429 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004430 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004431 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004432 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004433 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004434 if (size < 0)
4435 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004436 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004437}
4438
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004439
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004440PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004441"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004443
Barry Warsaw53699e91996-12-10 23:23:01 +00004444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004445posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004446{
4447 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004448 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004449 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004450 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004451 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004452 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004453 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004454 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004455 if (res != 0)
4456 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004457
Fred Drake699f3522000-06-29 21:12:41 +00004458 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004459}
4460
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004461
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004462PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004463"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004464Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004465
Barry Warsaw53699e91996-12-10 23:23:01 +00004466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004467posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004468{
Guido van Rossum687dd131993-05-17 08:34:16 +00004469 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004470 char *mode = "r";
4471 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004472 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004473 PyObject *f;
4474 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004475 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004476
Barry Warsaw53699e91996-12-10 23:23:01 +00004477 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004478 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004479 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004480 if (fp == NULL)
4481 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004482 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004483 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004484 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004485 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004486}
4487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004488PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004489"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004490Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004491connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004492
4493static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004494posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004495{
4496 int fd;
4497 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4498 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004499 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004500}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004501
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004502#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004503PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004504"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004505Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004506
Barry Warsaw53699e91996-12-10 23:23:01 +00004507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004508posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004509{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004510#if defined(PYOS_OS2)
4511 HFILE read, write;
4512 APIRET rc;
4513
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004514 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004515 return NULL;
4516
4517 Py_BEGIN_ALLOW_THREADS
4518 rc = DosCreatePipe( &read, &write, 4096);
4519 Py_END_ALLOW_THREADS
4520 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004521 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004522
4523 return Py_BuildValue("(ii)", read, write);
4524#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004525#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004526 int fds[2];
4527 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004528 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004529 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004530 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004531 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004532 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004533 if (res != 0)
4534 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004535 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004536#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004537 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004538 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004539 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004540 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004541 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004542 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004543 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004544 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004545 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004546 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004547 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4548 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004549 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004550#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004551#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004552}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004553#endif /* HAVE_PIPE */
4554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004555
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004556#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004557PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004558"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004559Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004560
Barry Warsaw53699e91996-12-10 23:23:01 +00004561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004562posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004563{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004564 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004565 int mode = 0666;
4566 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004567 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004568 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004569 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004570 res = mkfifo(filename, mode);
4571 Py_END_ALLOW_THREADS
4572 if (res < 0)
4573 return posix_error();
4574 Py_INCREF(Py_None);
4575 return Py_None;
4576}
4577#endif
4578
4579
4580#ifdef HAVE_MKNOD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004581PyDoc_STRVAR(posix_mknod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004582"mknod(filename, [, mode=0600, major, minor])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004583Create a filesystem node (file, device special file or named pipe)\n\
4584named filename. mode specifies both the permissions to use and the\n\
4585type of node to be created, being combined (bitwise OR) with one of\n\
4586S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4587major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004588they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004589
4590
4591static PyObject *
4592posix_mknod(PyObject *self, PyObject *args)
4593{
4594 char *filename;
4595 int mode = 0600;
4596 int major = 0;
4597 int minor = 0;
4598 int res;
4599 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4600 &mode, &major, &minor))
4601 return NULL;
4602 Py_BEGIN_ALLOW_THREADS
4603 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004604 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004605 if (res < 0)
4606 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004607 Py_INCREF(Py_None);
4608 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004609}
4610#endif
4611
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004612
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004613#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004614PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004615"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004616Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004617
Barry Warsaw53699e91996-12-10 23:23:01 +00004618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004619posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004620{
4621 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004622 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004623 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004624 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004625
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004626 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004627 return NULL;
4628
4629#if !defined(HAVE_LARGEFILE_SUPPORT)
4630 length = PyInt_AsLong(lenobj);
4631#else
4632 length = PyLong_Check(lenobj) ?
4633 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4634#endif
4635 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004636 return NULL;
4637
Barry Warsaw53699e91996-12-10 23:23:01 +00004638 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004639 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004640 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004641 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004642 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004643 return NULL;
4644 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004645 Py_INCREF(Py_None);
4646 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004647}
4648#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004649
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004650#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004651PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004652"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004653Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004654
Fred Drake762e2061999-08-26 17:23:54 +00004655/* Save putenv() parameters as values here, so we can collect them when they
4656 * get re-set with another call for the same key. */
4657static PyObject *posix_putenv_garbage;
4658
Tim Peters5aa91602002-01-30 05:46:57 +00004659static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004660posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004661{
4662 char *s1, *s2;
4663 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004664 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004665 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004666
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004667 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004668 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004669
4670#if defined(PYOS_OS2)
4671 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4672 APIRET rc;
4673
4674 if (strlen(s2) == 0) /* If New Value is an Empty String */
4675 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4676
4677 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4678 if (rc != NO_ERROR)
4679 return os2_error(rc);
4680
4681 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4682 APIRET rc;
4683
4684 if (strlen(s2) == 0) /* If New Value is an Empty String */
4685 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4686
4687 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4688 if (rc != NO_ERROR)
4689 return os2_error(rc);
4690 } else {
4691#endif
4692
Fred Drake762e2061999-08-26 17:23:54 +00004693 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004694 len = strlen(s1) + strlen(s2) + 2;
4695 /* len includes space for a trailing \0; the size arg to
4696 PyString_FromStringAndSize does not count that */
4697 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004698 if (newstr == NULL)
4699 return PyErr_NoMemory();
4700 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004701 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004702 if (putenv(new)) {
4703 posix_error();
4704 return NULL;
4705 }
Fred Drake762e2061999-08-26 17:23:54 +00004706 /* Install the first arg and newstr in posix_putenv_garbage;
4707 * this will cause previous value to be collected. This has to
4708 * happen after the real putenv() call because the old value
4709 * was still accessible until then. */
4710 if (PyDict_SetItem(posix_putenv_garbage,
4711 PyTuple_GET_ITEM(args, 0), newstr)) {
4712 /* really not much we can do; just leak */
4713 PyErr_Clear();
4714 }
4715 else {
4716 Py_DECREF(newstr);
4717 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004718
4719#if defined(PYOS_OS2)
4720 }
4721#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004722 Py_INCREF(Py_None);
4723 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004724}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004725#endif /* putenv */
4726
Guido van Rossumc524d952001-10-19 01:31:59 +00004727#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004728PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004729"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004730Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00004731
4732static PyObject *
4733posix_unsetenv(PyObject *self, PyObject *args)
4734{
4735 char *s1;
4736
4737 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4738 return NULL;
4739
4740 unsetenv(s1);
4741
4742 /* Remove the key from posix_putenv_garbage;
4743 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004744 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004745 * old value was still accessible until then.
4746 */
4747 if (PyDict_DelItem(posix_putenv_garbage,
4748 PyTuple_GET_ITEM(args, 0))) {
4749 /* really not much we can do; just leak */
4750 PyErr_Clear();
4751 }
4752
4753 Py_INCREF(Py_None);
4754 return Py_None;
4755}
4756#endif /* unsetenv */
4757
Guido van Rossumb6a47161997-09-15 22:54:34 +00004758#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004759PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004760"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004761Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004762
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004764posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004765{
4766 int code;
4767 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004768 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004769 return NULL;
4770 message = strerror(code);
4771 if (message == NULL) {
4772 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004773 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004774 return NULL;
4775 }
4776 return PyString_FromString(message);
4777}
4778#endif /* strerror */
4779
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004780
Guido van Rossumc9641791998-08-04 15:26:23 +00004781#ifdef HAVE_SYS_WAIT_H
4782
Fred Drake106c1a02002-04-23 15:58:02 +00004783#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004784PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004785"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004786Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00004787
4788static PyObject *
4789posix_WCOREDUMP(PyObject *self, PyObject *args)
4790{
4791#ifdef UNION_WAIT
4792 union wait status;
4793#define status_i (status.w_status)
4794#else
4795 int status;
4796#define status_i status
4797#endif
4798 status_i = 0;
4799
4800 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4801 {
4802 return NULL;
4803 }
4804
4805 return PyBool_FromLong(WCOREDUMP(status));
4806#undef status_i
4807}
4808#endif /* WCOREDUMP */
4809
4810#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004811PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004812"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004813Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004814job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00004815
4816static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004817posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004818{
4819#ifdef UNION_WAIT
4820 union wait status;
4821#define status_i (status.w_status)
4822#else
4823 int status;
4824#define status_i status
4825#endif
4826 status_i = 0;
4827
4828 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4829 {
4830 return NULL;
4831 }
4832
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004833 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004834#undef status_i
4835}
4836#endif /* WIFCONTINUED */
4837
Guido van Rossumc9641791998-08-04 15:26:23 +00004838#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004839PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004840"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004841Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004842
4843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004844posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004845{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004846#ifdef UNION_WAIT
4847 union wait status;
4848#define status_i (status.w_status)
4849#else
4850 int status;
4851#define status_i status
4852#endif
4853 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004854
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004855 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004856 {
4857 return NULL;
4858 }
Tim Peters5aa91602002-01-30 05:46:57 +00004859
Fred Drake106c1a02002-04-23 15:58:02 +00004860 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004861#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004862}
4863#endif /* WIFSTOPPED */
4864
4865#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004866PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004867"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004868Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004869
4870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004871posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004872{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004873#ifdef UNION_WAIT
4874 union wait status;
4875#define status_i (status.w_status)
4876#else
4877 int status;
4878#define status_i status
4879#endif
4880 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004881
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004882 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004883 {
4884 return NULL;
4885 }
Tim Peters5aa91602002-01-30 05:46:57 +00004886
Fred Drake106c1a02002-04-23 15:58:02 +00004887 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004888#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004889}
4890#endif /* WIFSIGNALED */
4891
4892#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004893PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004894"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004895Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004896system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004897
4898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004899posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004900{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004901#ifdef UNION_WAIT
4902 union wait status;
4903#define status_i (status.w_status)
4904#else
4905 int status;
4906#define status_i status
4907#endif
4908 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004909
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004910 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004911 {
4912 return NULL;
4913 }
Tim Peters5aa91602002-01-30 05:46:57 +00004914
Fred Drake106c1a02002-04-23 15:58:02 +00004915 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004916#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004917}
4918#endif /* WIFEXITED */
4919
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004920#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004921PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004922"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004923Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004924
4925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004926posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004927{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004928#ifdef UNION_WAIT
4929 union wait status;
4930#define status_i (status.w_status)
4931#else
4932 int status;
4933#define status_i status
4934#endif
4935 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004936
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004937 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004938 {
4939 return NULL;
4940 }
Tim Peters5aa91602002-01-30 05:46:57 +00004941
Guido van Rossumc9641791998-08-04 15:26:23 +00004942 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004943#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004944}
4945#endif /* WEXITSTATUS */
4946
4947#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004948PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004949"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004950Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004951value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004952
4953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004954posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004955{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004956#ifdef UNION_WAIT
4957 union wait status;
4958#define status_i (status.w_status)
4959#else
4960 int status;
4961#define status_i status
4962#endif
4963 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004964
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004965 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004966 {
4967 return NULL;
4968 }
Tim Peters5aa91602002-01-30 05:46:57 +00004969
Guido van Rossumc9641791998-08-04 15:26:23 +00004970 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004971#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004972}
4973#endif /* WTERMSIG */
4974
4975#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004976PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004977"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004978Return the signal that stopped the process that provided\n\
4979the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004980
4981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004982posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004983{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004984#ifdef UNION_WAIT
4985 union wait status;
4986#define status_i (status.w_status)
4987#else
4988 int status;
4989#define status_i status
4990#endif
4991 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004992
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004993 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004994 {
4995 return NULL;
4996 }
Tim Peters5aa91602002-01-30 05:46:57 +00004997
Guido van Rossumc9641791998-08-04 15:26:23 +00004998 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004999#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005000}
5001#endif /* WSTOPSIG */
5002
5003#endif /* HAVE_SYS_WAIT_H */
5004
5005
Guido van Rossum94f6f721999-01-06 18:42:14 +00005006#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005007#ifdef _SCO_DS
5008/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5009 needed definitions in sys/statvfs.h */
5010#define _SVID3
5011#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005012#include <sys/statvfs.h>
5013
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005014static PyObject*
5015_pystatvfs_fromstructstatvfs(struct statvfs st) {
5016 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5017 if (v == NULL)
5018 return NULL;
5019
5020#if !defined(HAVE_LARGEFILE_SUPPORT)
5021 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5022 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5023 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5024 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5025 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5026 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5027 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5028 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5029 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5030 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5031#else
5032 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5033 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005034 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005035 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005036 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005037 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5038 PyStructSequence_SET_ITEM(v, 4,
5039 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005040 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005041 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005042 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005043 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005044 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005045 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5046 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5047 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5048#endif
5049
5050 return v;
5051}
5052
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005053PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005054"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005055Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005056
5057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005058posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005059{
5060 int fd, res;
5061 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005062
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005063 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005064 return NULL;
5065 Py_BEGIN_ALLOW_THREADS
5066 res = fstatvfs(fd, &st);
5067 Py_END_ALLOW_THREADS
5068 if (res != 0)
5069 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005070
5071 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005072}
5073#endif /* HAVE_FSTATVFS */
5074
5075
5076#if defined(HAVE_STATVFS)
5077#include <sys/statvfs.h>
5078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005079PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005080"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005081Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005082
5083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005084posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005085{
5086 char *path;
5087 int res;
5088 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005089 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005090 return NULL;
5091 Py_BEGIN_ALLOW_THREADS
5092 res = statvfs(path, &st);
5093 Py_END_ALLOW_THREADS
5094 if (res != 0)
5095 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005096
5097 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005098}
5099#endif /* HAVE_STATVFS */
5100
5101
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005102#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005103PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005104"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005105Return a unique name for a temporary file.\n\
5106The directory and a short may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005107or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005108
5109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005110posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005111{
5112 PyObject *result = NULL;
5113 char *dir = NULL;
5114 char *pfx = NULL;
5115 char *name;
5116
5117 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5118 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005119
5120 if (PyErr_Warn(PyExc_RuntimeWarning,
5121 "tempnam is a potential security risk to your program") < 0)
5122 return NULL;
5123
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005124#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005125 name = _tempnam(dir, pfx);
5126#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005127 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005128#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005129 if (name == NULL)
5130 return PyErr_NoMemory();
5131 result = PyString_FromString(name);
5132 free(name);
5133 return result;
5134}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005135#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005136
5137
5138#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005139PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005140"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005141Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005142
5143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005144posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005145{
5146 FILE *fp;
5147
5148 if (!PyArg_ParseTuple(args, ":tmpfile"))
5149 return NULL;
5150 fp = tmpfile();
5151 if (fp == NULL)
5152 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005153 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005154}
5155#endif
5156
5157
5158#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005159PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005160"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005161Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005162
5163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005164posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005165{
5166 char buffer[L_tmpnam];
5167 char *name;
5168
5169 if (!PyArg_ParseTuple(args, ":tmpnam"))
5170 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005171
5172 if (PyErr_Warn(PyExc_RuntimeWarning,
5173 "tmpnam is a potential security risk to your program") < 0)
5174 return NULL;
5175
Greg Wardb48bc172000-03-01 21:51:56 +00005176#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005177 name = tmpnam_r(buffer);
5178#else
5179 name = tmpnam(buffer);
5180#endif
5181 if (name == NULL) {
5182 PyErr_SetObject(PyExc_OSError,
5183 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005184#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005185 "unexpected NULL from tmpnam_r"
5186#else
5187 "unexpected NULL from tmpnam"
5188#endif
5189 ));
5190 return NULL;
5191 }
5192 return PyString_FromString(buffer);
5193}
5194#endif
5195
5196
Fred Drakec9680921999-12-13 16:37:25 +00005197/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5198 * It maps strings representing configuration variable names to
5199 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005200 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005201 * rarely-used constants. There are three separate tables that use
5202 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005203 *
5204 * This code is always included, even if none of the interfaces that
5205 * need it are included. The #if hackery needed to avoid it would be
5206 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005207 */
5208struct constdef {
5209 char *name;
5210 long value;
5211};
5212
Fred Drake12c6e2d1999-12-14 21:25:03 +00005213static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005214conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5215 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005216{
5217 if (PyInt_Check(arg)) {
5218 *valuep = PyInt_AS_LONG(arg);
5219 return 1;
5220 }
5221 if (PyString_Check(arg)) {
5222 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005223 size_t lo = 0;
5224 size_t mid;
5225 size_t hi = tablesize;
5226 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005227 char *confname = PyString_AS_STRING(arg);
5228 while (lo < hi) {
5229 mid = (lo + hi) / 2;
5230 cmp = strcmp(confname, table[mid].name);
5231 if (cmp < 0)
5232 hi = mid;
5233 else if (cmp > 0)
5234 lo = mid + 1;
5235 else {
5236 *valuep = table[mid].value;
5237 return 1;
5238 }
5239 }
5240 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5241 }
5242 else
5243 PyErr_SetString(PyExc_TypeError,
5244 "configuration names must be strings or integers");
5245 return 0;
5246}
5247
5248
5249#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5250static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005251#ifdef _PC_ABI_AIO_XFER_MAX
5252 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5253#endif
5254#ifdef _PC_ABI_ASYNC_IO
5255 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5256#endif
Fred Drakec9680921999-12-13 16:37:25 +00005257#ifdef _PC_ASYNC_IO
5258 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5259#endif
5260#ifdef _PC_CHOWN_RESTRICTED
5261 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5262#endif
5263#ifdef _PC_FILESIZEBITS
5264 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5265#endif
5266#ifdef _PC_LAST
5267 {"PC_LAST", _PC_LAST},
5268#endif
5269#ifdef _PC_LINK_MAX
5270 {"PC_LINK_MAX", _PC_LINK_MAX},
5271#endif
5272#ifdef _PC_MAX_CANON
5273 {"PC_MAX_CANON", _PC_MAX_CANON},
5274#endif
5275#ifdef _PC_MAX_INPUT
5276 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5277#endif
5278#ifdef _PC_NAME_MAX
5279 {"PC_NAME_MAX", _PC_NAME_MAX},
5280#endif
5281#ifdef _PC_NO_TRUNC
5282 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5283#endif
5284#ifdef _PC_PATH_MAX
5285 {"PC_PATH_MAX", _PC_PATH_MAX},
5286#endif
5287#ifdef _PC_PIPE_BUF
5288 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5289#endif
5290#ifdef _PC_PRIO_IO
5291 {"PC_PRIO_IO", _PC_PRIO_IO},
5292#endif
5293#ifdef _PC_SOCK_MAXBUF
5294 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5295#endif
5296#ifdef _PC_SYNC_IO
5297 {"PC_SYNC_IO", _PC_SYNC_IO},
5298#endif
5299#ifdef _PC_VDISABLE
5300 {"PC_VDISABLE", _PC_VDISABLE},
5301#endif
5302};
5303
Fred Drakec9680921999-12-13 16:37:25 +00005304static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005305conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005306{
5307 return conv_confname(arg, valuep, posix_constants_pathconf,
5308 sizeof(posix_constants_pathconf)
5309 / sizeof(struct constdef));
5310}
5311#endif
5312
5313#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005314PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005315"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005316Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005317If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005318
5319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005320posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005321{
5322 PyObject *result = NULL;
5323 int name, fd;
5324
Fred Drake12c6e2d1999-12-14 21:25:03 +00005325 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5326 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005327 long limit;
5328
5329 errno = 0;
5330 limit = fpathconf(fd, name);
5331 if (limit == -1 && errno != 0)
5332 posix_error();
5333 else
5334 result = PyInt_FromLong(limit);
5335 }
5336 return result;
5337}
5338#endif
5339
5340
5341#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005342PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005343"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005344Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005345If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005346
5347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005348posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005349{
5350 PyObject *result = NULL;
5351 int name;
5352 char *path;
5353
5354 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5355 conv_path_confname, &name)) {
5356 long limit;
5357
5358 errno = 0;
5359 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005360 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005361 if (errno == EINVAL)
5362 /* could be a path or name problem */
5363 posix_error();
5364 else
5365 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005366 }
Fred Drakec9680921999-12-13 16:37:25 +00005367 else
5368 result = PyInt_FromLong(limit);
5369 }
5370 return result;
5371}
5372#endif
5373
5374#ifdef HAVE_CONFSTR
5375static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005376#ifdef _CS_ARCHITECTURE
5377 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5378#endif
5379#ifdef _CS_HOSTNAME
5380 {"CS_HOSTNAME", _CS_HOSTNAME},
5381#endif
5382#ifdef _CS_HW_PROVIDER
5383 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5384#endif
5385#ifdef _CS_HW_SERIAL
5386 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5387#endif
5388#ifdef _CS_INITTAB_NAME
5389 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5390#endif
Fred Drakec9680921999-12-13 16:37:25 +00005391#ifdef _CS_LFS64_CFLAGS
5392 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5393#endif
5394#ifdef _CS_LFS64_LDFLAGS
5395 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5396#endif
5397#ifdef _CS_LFS64_LIBS
5398 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5399#endif
5400#ifdef _CS_LFS64_LINTFLAGS
5401 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5402#endif
5403#ifdef _CS_LFS_CFLAGS
5404 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5405#endif
5406#ifdef _CS_LFS_LDFLAGS
5407 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5408#endif
5409#ifdef _CS_LFS_LIBS
5410 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5411#endif
5412#ifdef _CS_LFS_LINTFLAGS
5413 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5414#endif
Fred Draked86ed291999-12-15 15:34:33 +00005415#ifdef _CS_MACHINE
5416 {"CS_MACHINE", _CS_MACHINE},
5417#endif
Fred Drakec9680921999-12-13 16:37:25 +00005418#ifdef _CS_PATH
5419 {"CS_PATH", _CS_PATH},
5420#endif
Fred Draked86ed291999-12-15 15:34:33 +00005421#ifdef _CS_RELEASE
5422 {"CS_RELEASE", _CS_RELEASE},
5423#endif
5424#ifdef _CS_SRPC_DOMAIN
5425 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5426#endif
5427#ifdef _CS_SYSNAME
5428 {"CS_SYSNAME", _CS_SYSNAME},
5429#endif
5430#ifdef _CS_VERSION
5431 {"CS_VERSION", _CS_VERSION},
5432#endif
Fred Drakec9680921999-12-13 16:37:25 +00005433#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5434 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5435#endif
5436#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5437 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5438#endif
5439#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5440 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5441#endif
5442#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5443 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5444#endif
5445#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5446 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5447#endif
5448#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5449 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5450#endif
5451#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5452 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5453#endif
5454#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5455 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5456#endif
5457#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5458 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5459#endif
5460#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5461 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5462#endif
5463#ifdef _CS_XBS5_LP64_OFF64_LIBS
5464 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5465#endif
5466#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5467 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5468#endif
5469#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5470 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5471#endif
5472#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5473 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5474#endif
5475#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5476 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5477#endif
5478#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5479 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5480#endif
Fred Draked86ed291999-12-15 15:34:33 +00005481#ifdef _MIPS_CS_AVAIL_PROCESSORS
5482 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5483#endif
5484#ifdef _MIPS_CS_BASE
5485 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5486#endif
5487#ifdef _MIPS_CS_HOSTID
5488 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5489#endif
5490#ifdef _MIPS_CS_HW_NAME
5491 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5492#endif
5493#ifdef _MIPS_CS_NUM_PROCESSORS
5494 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5495#endif
5496#ifdef _MIPS_CS_OSREL_MAJ
5497 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5498#endif
5499#ifdef _MIPS_CS_OSREL_MIN
5500 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5501#endif
5502#ifdef _MIPS_CS_OSREL_PATCH
5503 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5504#endif
5505#ifdef _MIPS_CS_OS_NAME
5506 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5507#endif
5508#ifdef _MIPS_CS_OS_PROVIDER
5509 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5510#endif
5511#ifdef _MIPS_CS_PROCESSORS
5512 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5513#endif
5514#ifdef _MIPS_CS_SERIAL
5515 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5516#endif
5517#ifdef _MIPS_CS_VENDOR
5518 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5519#endif
Fred Drakec9680921999-12-13 16:37:25 +00005520};
5521
5522static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005523conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005524{
5525 return conv_confname(arg, valuep, posix_constants_confstr,
5526 sizeof(posix_constants_confstr)
5527 / sizeof(struct constdef));
5528}
5529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005530PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005531"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005532Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005533
5534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005535posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005536{
5537 PyObject *result = NULL;
5538 int name;
5539 char buffer[64];
5540
5541 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5542 int len = confstr(name, buffer, sizeof(buffer));
5543
Fred Drakec9680921999-12-13 16:37:25 +00005544 errno = 0;
5545 if (len == 0) {
5546 if (errno != 0)
5547 posix_error();
5548 else
5549 result = PyString_FromString("");
5550 }
5551 else {
5552 if (len >= sizeof(buffer)) {
5553 result = PyString_FromStringAndSize(NULL, len);
5554 if (result != NULL)
5555 confstr(name, PyString_AS_STRING(result), len+1);
5556 }
5557 else
5558 result = PyString_FromString(buffer);
5559 }
5560 }
5561 return result;
5562}
5563#endif
5564
5565
5566#ifdef HAVE_SYSCONF
5567static struct constdef posix_constants_sysconf[] = {
5568#ifdef _SC_2_CHAR_TERM
5569 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5570#endif
5571#ifdef _SC_2_C_BIND
5572 {"SC_2_C_BIND", _SC_2_C_BIND},
5573#endif
5574#ifdef _SC_2_C_DEV
5575 {"SC_2_C_DEV", _SC_2_C_DEV},
5576#endif
5577#ifdef _SC_2_C_VERSION
5578 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5579#endif
5580#ifdef _SC_2_FORT_DEV
5581 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5582#endif
5583#ifdef _SC_2_FORT_RUN
5584 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5585#endif
5586#ifdef _SC_2_LOCALEDEF
5587 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5588#endif
5589#ifdef _SC_2_SW_DEV
5590 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5591#endif
5592#ifdef _SC_2_UPE
5593 {"SC_2_UPE", _SC_2_UPE},
5594#endif
5595#ifdef _SC_2_VERSION
5596 {"SC_2_VERSION", _SC_2_VERSION},
5597#endif
Fred Draked86ed291999-12-15 15:34:33 +00005598#ifdef _SC_ABI_ASYNCHRONOUS_IO
5599 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5600#endif
5601#ifdef _SC_ACL
5602 {"SC_ACL", _SC_ACL},
5603#endif
Fred Drakec9680921999-12-13 16:37:25 +00005604#ifdef _SC_AIO_LISTIO_MAX
5605 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5606#endif
Fred Drakec9680921999-12-13 16:37:25 +00005607#ifdef _SC_AIO_MAX
5608 {"SC_AIO_MAX", _SC_AIO_MAX},
5609#endif
5610#ifdef _SC_AIO_PRIO_DELTA_MAX
5611 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5612#endif
5613#ifdef _SC_ARG_MAX
5614 {"SC_ARG_MAX", _SC_ARG_MAX},
5615#endif
5616#ifdef _SC_ASYNCHRONOUS_IO
5617 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5618#endif
5619#ifdef _SC_ATEXIT_MAX
5620 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5621#endif
Fred Draked86ed291999-12-15 15:34:33 +00005622#ifdef _SC_AUDIT
5623 {"SC_AUDIT", _SC_AUDIT},
5624#endif
Fred Drakec9680921999-12-13 16:37:25 +00005625#ifdef _SC_AVPHYS_PAGES
5626 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5627#endif
5628#ifdef _SC_BC_BASE_MAX
5629 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5630#endif
5631#ifdef _SC_BC_DIM_MAX
5632 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5633#endif
5634#ifdef _SC_BC_SCALE_MAX
5635 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5636#endif
5637#ifdef _SC_BC_STRING_MAX
5638 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5639#endif
Fred Draked86ed291999-12-15 15:34:33 +00005640#ifdef _SC_CAP
5641 {"SC_CAP", _SC_CAP},
5642#endif
Fred Drakec9680921999-12-13 16:37:25 +00005643#ifdef _SC_CHARCLASS_NAME_MAX
5644 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5645#endif
5646#ifdef _SC_CHAR_BIT
5647 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5648#endif
5649#ifdef _SC_CHAR_MAX
5650 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5651#endif
5652#ifdef _SC_CHAR_MIN
5653 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5654#endif
5655#ifdef _SC_CHILD_MAX
5656 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5657#endif
5658#ifdef _SC_CLK_TCK
5659 {"SC_CLK_TCK", _SC_CLK_TCK},
5660#endif
5661#ifdef _SC_COHER_BLKSZ
5662 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5663#endif
5664#ifdef _SC_COLL_WEIGHTS_MAX
5665 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5666#endif
5667#ifdef _SC_DCACHE_ASSOC
5668 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5669#endif
5670#ifdef _SC_DCACHE_BLKSZ
5671 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5672#endif
5673#ifdef _SC_DCACHE_LINESZ
5674 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5675#endif
5676#ifdef _SC_DCACHE_SZ
5677 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5678#endif
5679#ifdef _SC_DCACHE_TBLKSZ
5680 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5681#endif
5682#ifdef _SC_DELAYTIMER_MAX
5683 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5684#endif
5685#ifdef _SC_EQUIV_CLASS_MAX
5686 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5687#endif
5688#ifdef _SC_EXPR_NEST_MAX
5689 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5690#endif
5691#ifdef _SC_FSYNC
5692 {"SC_FSYNC", _SC_FSYNC},
5693#endif
5694#ifdef _SC_GETGR_R_SIZE_MAX
5695 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5696#endif
5697#ifdef _SC_GETPW_R_SIZE_MAX
5698 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5699#endif
5700#ifdef _SC_ICACHE_ASSOC
5701 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5702#endif
5703#ifdef _SC_ICACHE_BLKSZ
5704 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5705#endif
5706#ifdef _SC_ICACHE_LINESZ
5707 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5708#endif
5709#ifdef _SC_ICACHE_SZ
5710 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5711#endif
Fred Draked86ed291999-12-15 15:34:33 +00005712#ifdef _SC_INF
5713 {"SC_INF", _SC_INF},
5714#endif
Fred Drakec9680921999-12-13 16:37:25 +00005715#ifdef _SC_INT_MAX
5716 {"SC_INT_MAX", _SC_INT_MAX},
5717#endif
5718#ifdef _SC_INT_MIN
5719 {"SC_INT_MIN", _SC_INT_MIN},
5720#endif
5721#ifdef _SC_IOV_MAX
5722 {"SC_IOV_MAX", _SC_IOV_MAX},
5723#endif
Fred Draked86ed291999-12-15 15:34:33 +00005724#ifdef _SC_IP_SECOPTS
5725 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5726#endif
Fred Drakec9680921999-12-13 16:37:25 +00005727#ifdef _SC_JOB_CONTROL
5728 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5729#endif
Fred Draked86ed291999-12-15 15:34:33 +00005730#ifdef _SC_KERN_POINTERS
5731 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5732#endif
5733#ifdef _SC_KERN_SIM
5734 {"SC_KERN_SIM", _SC_KERN_SIM},
5735#endif
Fred Drakec9680921999-12-13 16:37:25 +00005736#ifdef _SC_LINE_MAX
5737 {"SC_LINE_MAX", _SC_LINE_MAX},
5738#endif
5739#ifdef _SC_LOGIN_NAME_MAX
5740 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5741#endif
5742#ifdef _SC_LOGNAME_MAX
5743 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5744#endif
5745#ifdef _SC_LONG_BIT
5746 {"SC_LONG_BIT", _SC_LONG_BIT},
5747#endif
Fred Draked86ed291999-12-15 15:34:33 +00005748#ifdef _SC_MAC
5749 {"SC_MAC", _SC_MAC},
5750#endif
Fred Drakec9680921999-12-13 16:37:25 +00005751#ifdef _SC_MAPPED_FILES
5752 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5753#endif
5754#ifdef _SC_MAXPID
5755 {"SC_MAXPID", _SC_MAXPID},
5756#endif
5757#ifdef _SC_MB_LEN_MAX
5758 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5759#endif
5760#ifdef _SC_MEMLOCK
5761 {"SC_MEMLOCK", _SC_MEMLOCK},
5762#endif
5763#ifdef _SC_MEMLOCK_RANGE
5764 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5765#endif
5766#ifdef _SC_MEMORY_PROTECTION
5767 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5768#endif
5769#ifdef _SC_MESSAGE_PASSING
5770 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5771#endif
Fred Draked86ed291999-12-15 15:34:33 +00005772#ifdef _SC_MMAP_FIXED_ALIGNMENT
5773 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5774#endif
Fred Drakec9680921999-12-13 16:37:25 +00005775#ifdef _SC_MQ_OPEN_MAX
5776 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5777#endif
5778#ifdef _SC_MQ_PRIO_MAX
5779 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5780#endif
Fred Draked86ed291999-12-15 15:34:33 +00005781#ifdef _SC_NACLS_MAX
5782 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5783#endif
Fred Drakec9680921999-12-13 16:37:25 +00005784#ifdef _SC_NGROUPS_MAX
5785 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5786#endif
5787#ifdef _SC_NL_ARGMAX
5788 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5789#endif
5790#ifdef _SC_NL_LANGMAX
5791 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5792#endif
5793#ifdef _SC_NL_MSGMAX
5794 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5795#endif
5796#ifdef _SC_NL_NMAX
5797 {"SC_NL_NMAX", _SC_NL_NMAX},
5798#endif
5799#ifdef _SC_NL_SETMAX
5800 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5801#endif
5802#ifdef _SC_NL_TEXTMAX
5803 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5804#endif
5805#ifdef _SC_NPROCESSORS_CONF
5806 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5807#endif
5808#ifdef _SC_NPROCESSORS_ONLN
5809 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5810#endif
Fred Draked86ed291999-12-15 15:34:33 +00005811#ifdef _SC_NPROC_CONF
5812 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5813#endif
5814#ifdef _SC_NPROC_ONLN
5815 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5816#endif
Fred Drakec9680921999-12-13 16:37:25 +00005817#ifdef _SC_NZERO
5818 {"SC_NZERO", _SC_NZERO},
5819#endif
5820#ifdef _SC_OPEN_MAX
5821 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5822#endif
5823#ifdef _SC_PAGESIZE
5824 {"SC_PAGESIZE", _SC_PAGESIZE},
5825#endif
5826#ifdef _SC_PAGE_SIZE
5827 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5828#endif
5829#ifdef _SC_PASS_MAX
5830 {"SC_PASS_MAX", _SC_PASS_MAX},
5831#endif
5832#ifdef _SC_PHYS_PAGES
5833 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5834#endif
5835#ifdef _SC_PII
5836 {"SC_PII", _SC_PII},
5837#endif
5838#ifdef _SC_PII_INTERNET
5839 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5840#endif
5841#ifdef _SC_PII_INTERNET_DGRAM
5842 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5843#endif
5844#ifdef _SC_PII_INTERNET_STREAM
5845 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5846#endif
5847#ifdef _SC_PII_OSI
5848 {"SC_PII_OSI", _SC_PII_OSI},
5849#endif
5850#ifdef _SC_PII_OSI_CLTS
5851 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5852#endif
5853#ifdef _SC_PII_OSI_COTS
5854 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5855#endif
5856#ifdef _SC_PII_OSI_M
5857 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5858#endif
5859#ifdef _SC_PII_SOCKET
5860 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5861#endif
5862#ifdef _SC_PII_XTI
5863 {"SC_PII_XTI", _SC_PII_XTI},
5864#endif
5865#ifdef _SC_POLL
5866 {"SC_POLL", _SC_POLL},
5867#endif
5868#ifdef _SC_PRIORITIZED_IO
5869 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5870#endif
5871#ifdef _SC_PRIORITY_SCHEDULING
5872 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5873#endif
5874#ifdef _SC_REALTIME_SIGNALS
5875 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5876#endif
5877#ifdef _SC_RE_DUP_MAX
5878 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5879#endif
5880#ifdef _SC_RTSIG_MAX
5881 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5882#endif
5883#ifdef _SC_SAVED_IDS
5884 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5885#endif
5886#ifdef _SC_SCHAR_MAX
5887 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5888#endif
5889#ifdef _SC_SCHAR_MIN
5890 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5891#endif
5892#ifdef _SC_SELECT
5893 {"SC_SELECT", _SC_SELECT},
5894#endif
5895#ifdef _SC_SEMAPHORES
5896 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5897#endif
5898#ifdef _SC_SEM_NSEMS_MAX
5899 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5900#endif
5901#ifdef _SC_SEM_VALUE_MAX
5902 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5903#endif
5904#ifdef _SC_SHARED_MEMORY_OBJECTS
5905 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5906#endif
5907#ifdef _SC_SHRT_MAX
5908 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5909#endif
5910#ifdef _SC_SHRT_MIN
5911 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5912#endif
5913#ifdef _SC_SIGQUEUE_MAX
5914 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5915#endif
5916#ifdef _SC_SIGRT_MAX
5917 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5918#endif
5919#ifdef _SC_SIGRT_MIN
5920 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5921#endif
Fred Draked86ed291999-12-15 15:34:33 +00005922#ifdef _SC_SOFTPOWER
5923 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5924#endif
Fred Drakec9680921999-12-13 16:37:25 +00005925#ifdef _SC_SPLIT_CACHE
5926 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5927#endif
5928#ifdef _SC_SSIZE_MAX
5929 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5930#endif
5931#ifdef _SC_STACK_PROT
5932 {"SC_STACK_PROT", _SC_STACK_PROT},
5933#endif
5934#ifdef _SC_STREAM_MAX
5935 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5936#endif
5937#ifdef _SC_SYNCHRONIZED_IO
5938 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5939#endif
5940#ifdef _SC_THREADS
5941 {"SC_THREADS", _SC_THREADS},
5942#endif
5943#ifdef _SC_THREAD_ATTR_STACKADDR
5944 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5945#endif
5946#ifdef _SC_THREAD_ATTR_STACKSIZE
5947 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5948#endif
5949#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5950 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5951#endif
5952#ifdef _SC_THREAD_KEYS_MAX
5953 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5954#endif
5955#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5956 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5957#endif
5958#ifdef _SC_THREAD_PRIO_INHERIT
5959 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5960#endif
5961#ifdef _SC_THREAD_PRIO_PROTECT
5962 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5963#endif
5964#ifdef _SC_THREAD_PROCESS_SHARED
5965 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5966#endif
5967#ifdef _SC_THREAD_SAFE_FUNCTIONS
5968 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5969#endif
5970#ifdef _SC_THREAD_STACK_MIN
5971 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5972#endif
5973#ifdef _SC_THREAD_THREADS_MAX
5974 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5975#endif
5976#ifdef _SC_TIMERS
5977 {"SC_TIMERS", _SC_TIMERS},
5978#endif
5979#ifdef _SC_TIMER_MAX
5980 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5981#endif
5982#ifdef _SC_TTY_NAME_MAX
5983 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5984#endif
5985#ifdef _SC_TZNAME_MAX
5986 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5987#endif
5988#ifdef _SC_T_IOV_MAX
5989 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5990#endif
5991#ifdef _SC_UCHAR_MAX
5992 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5993#endif
5994#ifdef _SC_UINT_MAX
5995 {"SC_UINT_MAX", _SC_UINT_MAX},
5996#endif
5997#ifdef _SC_UIO_MAXIOV
5998 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5999#endif
6000#ifdef _SC_ULONG_MAX
6001 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6002#endif
6003#ifdef _SC_USHRT_MAX
6004 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6005#endif
6006#ifdef _SC_VERSION
6007 {"SC_VERSION", _SC_VERSION},
6008#endif
6009#ifdef _SC_WORD_BIT
6010 {"SC_WORD_BIT", _SC_WORD_BIT},
6011#endif
6012#ifdef _SC_XBS5_ILP32_OFF32
6013 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6014#endif
6015#ifdef _SC_XBS5_ILP32_OFFBIG
6016 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6017#endif
6018#ifdef _SC_XBS5_LP64_OFF64
6019 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6020#endif
6021#ifdef _SC_XBS5_LPBIG_OFFBIG
6022 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6023#endif
6024#ifdef _SC_XOPEN_CRYPT
6025 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6026#endif
6027#ifdef _SC_XOPEN_ENH_I18N
6028 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6029#endif
6030#ifdef _SC_XOPEN_LEGACY
6031 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6032#endif
6033#ifdef _SC_XOPEN_REALTIME
6034 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6035#endif
6036#ifdef _SC_XOPEN_REALTIME_THREADS
6037 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6038#endif
6039#ifdef _SC_XOPEN_SHM
6040 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6041#endif
6042#ifdef _SC_XOPEN_UNIX
6043 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6044#endif
6045#ifdef _SC_XOPEN_VERSION
6046 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6047#endif
6048#ifdef _SC_XOPEN_XCU_VERSION
6049 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6050#endif
6051#ifdef _SC_XOPEN_XPG2
6052 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6053#endif
6054#ifdef _SC_XOPEN_XPG3
6055 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6056#endif
6057#ifdef _SC_XOPEN_XPG4
6058 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6059#endif
6060};
6061
6062static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006063conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006064{
6065 return conv_confname(arg, valuep, posix_constants_sysconf,
6066 sizeof(posix_constants_sysconf)
6067 / sizeof(struct constdef));
6068}
6069
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006070PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006071"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006072Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006073
6074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006075posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006076{
6077 PyObject *result = NULL;
6078 int name;
6079
6080 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6081 int value;
6082
6083 errno = 0;
6084 value = sysconf(name);
6085 if (value == -1 && errno != 0)
6086 posix_error();
6087 else
6088 result = PyInt_FromLong(value);
6089 }
6090 return result;
6091}
6092#endif
6093
6094
Fred Drakebec628d1999-12-15 18:31:10 +00006095/* This code is used to ensure that the tables of configuration value names
6096 * are in sorted order as required by conv_confname(), and also to build the
6097 * the exported dictionaries that are used to publish information about the
6098 * names available on the host platform.
6099 *
6100 * Sorting the table at runtime ensures that the table is properly ordered
6101 * when used, even for platforms we're not able to test on. It also makes
6102 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006103 */
Fred Drakebec628d1999-12-15 18:31:10 +00006104
6105static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006106cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006107{
6108 const struct constdef *c1 =
6109 (const struct constdef *) v1;
6110 const struct constdef *c2 =
6111 (const struct constdef *) v2;
6112
6113 return strcmp(c1->name, c2->name);
6114}
6115
6116static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006117setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006118 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006119{
Fred Drakebec628d1999-12-15 18:31:10 +00006120 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006121 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006122
6123 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6124 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006125 if (d == NULL)
6126 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006127
Barry Warsaw3155db32000-04-13 15:20:40 +00006128 for (i=0; i < tablesize; ++i) {
6129 PyObject *o = PyInt_FromLong(table[i].value);
6130 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6131 Py_XDECREF(o);
6132 Py_DECREF(d);
6133 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006134 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006135 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006136 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006137 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006138}
6139
Fred Drakebec628d1999-12-15 18:31:10 +00006140/* Return -1 on failure, 0 on success. */
6141static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006142setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006143{
6144#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006145 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006146 sizeof(posix_constants_pathconf)
6147 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006148 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006149 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006150#endif
6151#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006152 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006153 sizeof(posix_constants_confstr)
6154 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006155 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006156 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006157#endif
6158#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006159 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006160 sizeof(posix_constants_sysconf)
6161 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006162 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006163 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006164#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006165 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006166}
Fred Draked86ed291999-12-15 15:34:33 +00006167
6168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006169PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006170"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006171Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006173
6174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006175posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006176{
6177 if (!PyArg_ParseTuple(args, ":abort"))
6178 return NULL;
6179 abort();
6180 /*NOTREACHED*/
6181 Py_FatalError("abort() called from Python code didn't abort!");
6182 return NULL;
6183}
Fred Drakebec628d1999-12-15 18:31:10 +00006184
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006185#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006186PyDoc_STRVAR(win32_startfile__doc__,
6187"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006188\n\
6189This acts like double-clicking the file in Explorer, or giving the file\n\
6190name as an argument to the DOS \"start\" command: the file is opened\n\
6191with whatever application (if any) its extension is associated.\n\
6192\n\
6193startfile returns as soon as the associated application is launched.\n\
6194There is no option to wait for the application to close, and no way\n\
6195to retrieve the application's exit status.\n\
6196\n\
6197The filepath is relative to the current directory. If you want to use\n\
6198an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006199the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006200
6201static PyObject *
6202win32_startfile(PyObject *self, PyObject *args)
6203{
6204 char *filepath;
6205 HINSTANCE rc;
6206 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6207 return NULL;
6208 Py_BEGIN_ALLOW_THREADS
6209 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6210 Py_END_ALLOW_THREADS
6211 if (rc <= (HINSTANCE)32)
6212 return win32_error("startfile", filepath);
6213 Py_INCREF(Py_None);
6214 return Py_None;
6215}
6216#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006217
6218static PyMethodDef posix_methods[] = {
6219 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6220#ifdef HAVE_TTYNAME
6221 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6222#endif
6223 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6224 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006225#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006226 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006227#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006228#ifdef HAVE_CHROOT
6229 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6230#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006231#ifdef HAVE_CTERMID
6232 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6233#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006234#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006235 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006236#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006237#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006238 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006239#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006240 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6241 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6242 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006243#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006244 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006245#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006246#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006247 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006248#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006249 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6250 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6251 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006252#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006253 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006254#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006255#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006256 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006257#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006258 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006259#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006260 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006261#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006262 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6263 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6264 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006265#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006266 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006267#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006268 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006269#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006270 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6271 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006272#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006273#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006274 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6275 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006276#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006277#ifdef HAVE_FORK1
6278 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6279#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006280#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006281 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006282#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006283#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006284 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006285#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006286#ifdef HAVE_FORKPTY
6287 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6288#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006289#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006290 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006291#endif /* HAVE_GETEGID */
6292#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006293 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006294#endif /* HAVE_GETEUID */
6295#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006296 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006297#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006298#ifdef HAVE_GETGROUPS
6299 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6300#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006301 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006302#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006303 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006304#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006305#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006306 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006307#endif /* HAVE_GETPPID */
6308#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006309 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006310#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006311#ifdef HAVE_GETLOGIN
6312 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6313#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006314#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006315 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006316#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006317#ifdef HAVE_KILLPG
6318 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6319#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006320#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006321 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006322#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006323#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006324 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006325#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006326 {"popen2", win32_popen2, METH_VARARGS},
6327 {"popen3", win32_popen3, METH_VARARGS},
6328 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006329 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006330#else
6331#if defined(PYOS_OS2) && defined(PYCC_GCC)
6332 {"popen2", os2emx_popen2, METH_VARARGS},
6333 {"popen3", os2emx_popen3, METH_VARARGS},
6334 {"popen4", os2emx_popen4, METH_VARARGS},
6335#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006336#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006337#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006338#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006339 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006340#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006341#ifdef HAVE_SETEUID
6342 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6343#endif /* HAVE_SETEUID */
6344#ifdef HAVE_SETEGID
6345 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6346#endif /* HAVE_SETEGID */
6347#ifdef HAVE_SETREUID
6348 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6349#endif /* HAVE_SETREUID */
6350#ifdef HAVE_SETREGID
6351 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6352#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006353#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006354 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006355#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006356#ifdef HAVE_SETGROUPS
6357 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6358#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006359#ifdef HAVE_GETPGID
6360 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6361#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006362#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006363 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006364#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006365#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006366 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006367#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006368#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006369 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006370#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006371#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006372 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006373#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006374#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006375 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006376#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006377#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006378 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006379#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006380#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006381 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006382#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006383 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6384 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6385 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6386 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6387 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6388 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6389 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6390 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6391 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006392 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006393#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006394 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006395#endif
6396#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006397 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006398#endif
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006399#ifdef HAVE_MKNOD
6400 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6401#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006402#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006403 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006404#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006405#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006406 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006407#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006408#ifdef HAVE_UNSETENV
6409 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6410#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006411#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006412 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006413#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006414#ifdef HAVE_FCHDIR
6415 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6416#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006417#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006418 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006419#endif
6420#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006421 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006422#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006423#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006424#ifdef WCOREDUMP
6425 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6426#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006427#ifdef WIFCONTINUED
6428 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6429#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006430#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006431 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006432#endif /* WIFSTOPPED */
6433#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006434 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006435#endif /* WIFSIGNALED */
6436#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006437 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006438#endif /* WIFEXITED */
6439#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006440 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006441#endif /* WEXITSTATUS */
6442#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006443 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006444#endif /* WTERMSIG */
6445#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006446 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006447#endif /* WSTOPSIG */
6448#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006449#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006450 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006451#endif
6452#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006453 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006454#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006455#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006456 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6457#endif
6458#ifdef HAVE_TEMPNAM
6459 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6460#endif
6461#ifdef HAVE_TMPNAM
6462 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6463#endif
Fred Drakec9680921999-12-13 16:37:25 +00006464#ifdef HAVE_CONFSTR
6465 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6466#endif
6467#ifdef HAVE_SYSCONF
6468 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6469#endif
6470#ifdef HAVE_FPATHCONF
6471 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6472#endif
6473#ifdef HAVE_PATHCONF
6474 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6475#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006476 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006477#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006478 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6479#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006480 {NULL, NULL} /* Sentinel */
6481};
6482
6483
Barry Warsaw4a342091996-12-19 23:50:02 +00006484static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006485ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006486{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006487 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006488}
6489
Guido van Rossumd48f2521997-12-05 22:19:34 +00006490#if defined(PYOS_OS2)
6491/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006492static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006493{
6494 APIRET rc;
6495 ULONG values[QSV_MAX+1];
6496 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006497 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006498
6499 Py_BEGIN_ALLOW_THREADS
6500 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6501 Py_END_ALLOW_THREADS
6502
6503 if (rc != NO_ERROR) {
6504 os2_error(rc);
6505 return -1;
6506 }
6507
Fred Drake4d1e64b2002-04-15 19:40:07 +00006508 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6509 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6510 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6511 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6512 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6513 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6514 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006515
6516 switch (values[QSV_VERSION_MINOR]) {
6517 case 0: ver = "2.00"; break;
6518 case 10: ver = "2.10"; break;
6519 case 11: ver = "2.11"; break;
6520 case 30: ver = "3.00"; break;
6521 case 40: ver = "4.00"; break;
6522 case 50: ver = "5.00"; break;
6523 default:
Tim Peters885d4572001-11-28 20:27:42 +00006524 PyOS_snprintf(tmp, sizeof(tmp),
6525 "%d-%d", values[QSV_VERSION_MAJOR],
6526 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006527 ver = &tmp[0];
6528 }
6529
6530 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006531 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006532 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006533
6534 /* Add Indicator of Which Drive was Used to Boot the System */
6535 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6536 tmp[1] = ':';
6537 tmp[2] = '\0';
6538
Fred Drake4d1e64b2002-04-15 19:40:07 +00006539 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006540}
6541#endif
6542
Barry Warsaw4a342091996-12-19 23:50:02 +00006543static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006544all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006545{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006546#ifdef F_OK
6547 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006548#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006549#ifdef R_OK
6550 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006551#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006552#ifdef W_OK
6553 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006554#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006555#ifdef X_OK
6556 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006557#endif
Fred Drakec9680921999-12-13 16:37:25 +00006558#ifdef NGROUPS_MAX
6559 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6560#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006561#ifdef TMP_MAX
6562 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6563#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006564#ifdef WCONTINUED
6565 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6566#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006567#ifdef WNOHANG
6568 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006569#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006570#ifdef WUNTRACED
6571 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6572#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006573#ifdef O_RDONLY
6574 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6575#endif
6576#ifdef O_WRONLY
6577 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6578#endif
6579#ifdef O_RDWR
6580 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6581#endif
6582#ifdef O_NDELAY
6583 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6584#endif
6585#ifdef O_NONBLOCK
6586 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6587#endif
6588#ifdef O_APPEND
6589 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6590#endif
6591#ifdef O_DSYNC
6592 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6593#endif
6594#ifdef O_RSYNC
6595 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6596#endif
6597#ifdef O_SYNC
6598 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6599#endif
6600#ifdef O_NOCTTY
6601 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6602#endif
6603#ifdef O_CREAT
6604 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6605#endif
6606#ifdef O_EXCL
6607 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6608#endif
6609#ifdef O_TRUNC
6610 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6611#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006612#ifdef O_BINARY
6613 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6614#endif
6615#ifdef O_TEXT
6616 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6617#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006618#ifdef O_LARGEFILE
6619 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6620#endif
6621
Tim Peters5aa91602002-01-30 05:46:57 +00006622/* MS Windows */
6623#ifdef O_NOINHERIT
6624 /* Don't inherit in child processes. */
6625 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6626#endif
6627#ifdef _O_SHORT_LIVED
6628 /* Optimize for short life (keep in memory). */
6629 /* MS forgot to define this one with a non-underscore form too. */
6630 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6631#endif
6632#ifdef O_TEMPORARY
6633 /* Automatically delete when last handle is closed. */
6634 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6635#endif
6636#ifdef O_RANDOM
6637 /* Optimize for random access. */
6638 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6639#endif
6640#ifdef O_SEQUENTIAL
6641 /* Optimize for sequential access. */
6642 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6643#endif
6644
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006645/* GNU extensions. */
6646#ifdef O_DIRECT
6647 /* Direct disk access. */
6648 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6649#endif
6650#ifdef O_DIRECTORY
6651 /* Must be a directory. */
6652 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6653#endif
6654#ifdef O_NOFOLLOW
6655 /* Do not follow links. */
6656 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6657#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006658
Guido van Rossum246bc171999-02-01 23:54:31 +00006659#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006660#if defined(PYOS_OS2) && defined(PYCC_GCC)
6661 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6662 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6663 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6664 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6665 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6666 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6667 if (ins(d, "P_PM", (long)P_PM)) return -1;
6668 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6669 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6670 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6671 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6672 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6673 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6674 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6675 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6676 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6677 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6678 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6679 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6680 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6681#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006682 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6683 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6684 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6685 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6686 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006687#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006688#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006689
Guido van Rossumd48f2521997-12-05 22:19:34 +00006690#if defined(PYOS_OS2)
6691 if (insertvalues(d)) return -1;
6692#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006693 return 0;
6694}
6695
6696
Tim Peters5aa91602002-01-30 05:46:57 +00006697#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006698#define INITFUNC initnt
6699#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006700
6701#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006702#define INITFUNC initos2
6703#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006704
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006705#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006706#define INITFUNC initposix
6707#define MODNAME "posix"
6708#endif
6709
Guido van Rossum3886bb61998-12-04 18:50:17 +00006710DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006711INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006712{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006713 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006714
Fred Drake4d1e64b2002-04-15 19:40:07 +00006715 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006716 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006717 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006718
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006719 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006720 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006721 Py_XINCREF(v);
6722 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006723 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006724 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006725
Fred Drake4d1e64b2002-04-15 19:40:07 +00006726 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006727 return;
6728
Fred Drake4d1e64b2002-04-15 19:40:07 +00006729 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006730 return;
6731
Fred Drake4d1e64b2002-04-15 19:40:07 +00006732 Py_INCREF(PyExc_OSError);
6733 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006734
Guido van Rossumb3d39562000-01-31 18:41:26 +00006735#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006736 if (posix_putenv_garbage == NULL)
6737 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006738#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006739
Guido van Rossum14648392001-12-08 18:02:58 +00006740 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006741 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006742 Py_INCREF((PyObject*) &StatResultType);
6743 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006744
Guido van Rossum14648392001-12-08 18:02:58 +00006745 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006746 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006747 Py_INCREF((PyObject*) &StatVFSResultType);
6748 PyModule_AddObject(m, "statvfs_result",
6749 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006750}