blob: 8a419c3ad809545adb028f161d33420db5a4733a [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 Peters7a1f9172002-07-14 22:14:19 +0000220/* We don't want WIN32_LEAN_AND_MEAN here -- we need ShellExecute(). */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <windows.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000222#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000223#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000224#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225
Guido van Rossumd48f2521997-12-05 22:19:34 +0000226#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000228#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229
Tim Petersbc2e10e2002-03-03 23:17:02 +0000230#ifndef MAXPATHLEN
231#define MAXPATHLEN 1024
232#endif /* MAXPATHLEN */
233
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000234#ifdef UNION_WAIT
235/* Emulate some macros on systems that have a union instead of macros */
236
237#ifndef WIFEXITED
238#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
239#endif
240
241#ifndef WEXITSTATUS
242#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
243#endif
244
245#ifndef WTERMSIG
246#define WTERMSIG(u_wait) ((u_wait).w_termsig)
247#endif
248
249#endif /* UNION_WAIT */
250
Greg Wardb48bc172000-03-01 21:51:56 +0000251/* Don't use the "_r" form if we don't need it (also, won't have a
252 prototype for it, at least on Solaris -- maybe others as well?). */
253#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
254#define USE_CTERMID_R
255#endif
256
257#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
258#define USE_TMPNAM_R
259#endif
260
Fred Drake699f3522000-06-29 21:12:41 +0000261/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000262#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000263#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000264# define STAT _stati64
265# define FSTAT _fstati64
266# define STRUCT_STAT struct _stati64
267#else
268# define STAT stat
269# define FSTAT fstat
270# define STRUCT_STAT struct stat
271#endif
272
Neal Norwitz3d949422002-04-20 13:46:43 +0000273#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
274#include <sys/mkdev.h>
275#endif
Fred Drake699f3522000-06-29 21:12:41 +0000276
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277/* Return a dictionary corresponding to the POSIX environment table */
278
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000279#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000281#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282
Barry Warsaw53699e91996-12-10 23:23:01 +0000283static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000284convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285{
Barry Warsaw53699e91996-12-10 23:23:01 +0000286 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000288 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 if (d == NULL)
290 return NULL;
291 if (environ == NULL)
292 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000293 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000295 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000296 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 char *p = strchr(*e, '=');
298 if (p == NULL)
299 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000300 k = PyString_FromStringAndSize(*e, (int)(p-*e));
301 if (k == NULL) {
302 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000304 }
305 v = PyString_FromString(p+1);
306 if (v == NULL) {
307 PyErr_Clear();
308 Py_DECREF(k);
309 continue;
310 }
311 if (PyDict_GetItem(d, k) == NULL) {
312 if (PyDict_SetItem(d, k, v) != 0)
313 PyErr_Clear();
314 }
315 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000316 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000318#if defined(PYOS_OS2)
319 {
320 APIRET rc;
321 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
322
323 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000324 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000325 PyObject *v = PyString_FromString(buffer);
326 PyDict_SetItemString(d, "BEGINLIBPATH", v);
327 Py_DECREF(v);
328 }
329 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
330 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
331 PyObject *v = PyString_FromString(buffer);
332 PyDict_SetItemString(d, "ENDLIBPATH", v);
333 Py_DECREF(v);
334 }
335 }
336#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337 return d;
338}
339
340
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341/* Set a POSIX-specific error from errno, and return NULL */
342
Barry Warsawd58d7641998-07-23 16:14:40 +0000343static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000344posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000345{
Barry Warsawca74da41999-02-09 19:31:45 +0000346 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347}
Barry Warsawd58d7641998-07-23 16:14:40 +0000348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000349posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000350{
Barry Warsawca74da41999-02-09 19:31:45 +0000351 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000352}
353
Mark Hammondef8b6542001-05-13 08:04:26 +0000354static PyObject *
355posix_error_with_allocated_filename(char* name)
356{
357 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
358 PyMem_Free(name);
359 return rc;
360}
361
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000362#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000363static PyObject *
364win32_error(char* function, char* filename)
365{
Mark Hammond33a6da92000-08-15 00:46:38 +0000366 /* XXX We should pass the function name along in the future.
367 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000368 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000369 Windows error object, which is non-trivial.
370 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000371 errno = GetLastError();
372 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000373 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000374 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000375 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000376}
377#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000378
Guido van Rossumd48f2521997-12-05 22:19:34 +0000379#if defined(PYOS_OS2)
380/**********************************************************************
381 * Helper Function to Trim and Format OS/2 Messages
382 **********************************************************************/
383 static void
384os2_formatmsg(char *msgbuf, int msglen, char *reason)
385{
386 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
387
388 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
389 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
390
391 while (lastc > msgbuf && isspace(*lastc))
392 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
393 }
394
395 /* Add Optional Reason Text */
396 if (reason) {
397 strcat(msgbuf, " : ");
398 strcat(msgbuf, reason);
399 }
400}
401
402/**********************************************************************
403 * Decode an OS/2 Operating System Error Code
404 *
405 * A convenience function to lookup an OS/2 error code and return a
406 * text message we can use to raise a Python exception.
407 *
408 * Notes:
409 * The messages for errors returned from the OS/2 kernel reside in
410 * the file OSO001.MSG in the \OS2 directory hierarchy.
411 *
412 **********************************************************************/
413 static char *
414os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
415{
416 APIRET rc;
417 ULONG msglen;
418
419 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
420 Py_BEGIN_ALLOW_THREADS
421 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
422 errorcode, "oso001.msg", &msglen);
423 Py_END_ALLOW_THREADS
424
425 if (rc == NO_ERROR)
426 os2_formatmsg(msgbuf, msglen, reason);
427 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000428 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000429 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000430
431 return msgbuf;
432}
433
434/* Set an OS/2-specific error and return NULL. OS/2 kernel
435 errors are not in a global variable e.g. 'errno' nor are
436 they congruent with posix error numbers. */
437
438static PyObject * os2_error(int code)
439{
440 char text[1024];
441 PyObject *v;
442
443 os2_strerror(text, sizeof(text), code, "");
444
445 v = Py_BuildValue("(is)", code, text);
446 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000447 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000448 Py_DECREF(v);
449 }
450 return NULL; /* Signal to Python that an Exception is Pending */
451}
452
453#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000454
455/* POSIX generic methods */
456
Barry Warsaw53699e91996-12-10 23:23:01 +0000457static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000458posix_fildes(PyObject *fdobj, int (*func)(int))
459{
460 int fd;
461 int res;
462 fd = PyObject_AsFileDescriptor(fdobj);
463 if (fd < 0)
464 return NULL;
465 Py_BEGIN_ALLOW_THREADS
466 res = (*func)(fd);
467 Py_END_ALLOW_THREADS
468 if (res < 0)
469 return posix_error();
470 Py_INCREF(Py_None);
471 return Py_None;
472}
Guido van Rossum21142a01999-01-08 21:05:37 +0000473
474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000475posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000476{
Mark Hammondef8b6542001-05-13 08:04:26 +0000477 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000478 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000479 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000480 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000482 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000483 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000484 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000486 return posix_error_with_allocated_filename(path1);
487 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000488 Py_INCREF(Py_None);
489 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000490}
491
Barry Warsaw53699e91996-12-10 23:23:01 +0000492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000493posix_2str(PyObject *args, char *format,
494 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000495{
Mark Hammondef8b6542001-05-13 08:04:26 +0000496 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000497 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000498 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000499 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000500 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000502 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000503 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000504 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000505 PyMem_Free(path1);
506 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000507 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000508 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000510 Py_INCREF(Py_None);
511 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000512}
513
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000514PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000515"stat_result: Result from stat or lstat.\n\n\
516This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000517 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000518or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
519\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000520Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000521they are available as attributes only.\n\
522\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000523See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000524
525static PyStructSequence_Field stat_result_fields[] = {
526 {"st_mode", "protection bits"},
527 {"st_ino", "inode"},
528 {"st_dev", "device"},
529 {"st_nlink", "number of hard links"},
530 {"st_uid", "user ID of owner"},
531 {"st_gid", "group ID of owner"},
532 {"st_size", "total size, in bytes"},
533 {"st_atime", "time of last access"},
534 {"st_mtime", "time of last modification"},
535 {"st_ctime", "time of last change"},
536#ifdef HAVE_ST_BLKSIZE
537 {"st_blksize", "blocksize for filesystem I/O"},
538#endif
539#ifdef HAVE_ST_BLOCKS
540 {"st_blocks", "number of blocks allocated"},
541#endif
542#ifdef HAVE_ST_RDEV
543 {"st_rdev", "device type (if inode device)"},
544#endif
545 {0}
546};
547
548#ifdef HAVE_ST_BLKSIZE
549#define ST_BLKSIZE_IDX 10
550#else
551#define ST_BLKSIZE_IDX 9
552#endif
553
554#ifdef HAVE_ST_BLOCKS
555#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
556#else
557#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
558#endif
559
560#ifdef HAVE_ST_RDEV
561#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
562#else
563#define ST_RDEV_IDX ST_BLOCKS_IDX
564#endif
565
566static PyStructSequence_Desc stat_result_desc = {
567 "stat_result", /* name */
568 stat_result__doc__, /* doc */
569 stat_result_fields,
570 10
571};
572
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000573PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000574"statvfs_result: Result from statvfs or fstatvfs.\n\n\
575This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000576 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000577or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000578\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000579See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000580
581static PyStructSequence_Field statvfs_result_fields[] = {
582 {"f_bsize", },
583 {"f_frsize", },
584 {"f_blocks", },
585 {"f_bfree", },
586 {"f_bavail", },
587 {"f_files", },
588 {"f_ffree", },
589 {"f_favail", },
590 {"f_flag", },
591 {"f_namemax",},
592 {0}
593};
594
595static PyStructSequence_Desc statvfs_result_desc = {
596 "statvfs_result", /* name */
597 statvfs_result__doc__, /* doc */
598 statvfs_result_fields,
599 10
600};
601
602static PyTypeObject StatResultType;
603static PyTypeObject StatVFSResultType;
604
Tim Peters5aa91602002-01-30 05:46:57 +0000605/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000606 (used by posix_stat() and posix_fstat()) */
607static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000608_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000609{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000610 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000611 if (v == NULL)
612 return NULL;
613
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000614 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000615#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000616 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000617 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000618#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000619 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000620#endif
621#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000622 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000623 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000624#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000625 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000626#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000627 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
628 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
629 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000630#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000631 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000632 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000633#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000634 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000635#endif
636#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000637 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000638 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000639 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000640 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000641 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000642 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000643#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000644 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
645 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
646 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
647#endif
648
649#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000650 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000651 PyInt_FromLong((long)st.st_blksize));
652#endif
653#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000654 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000655 PyInt_FromLong((long)st.st_blocks));
656#endif
657#ifdef HAVE_ST_RDEV
658 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
659 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000660#endif
661
662 if (PyErr_Occurred()) {
663 Py_DECREF(v);
664 return NULL;
665 }
666
667 return v;
668}
669
Barry Warsaw53699e91996-12-10 23:23:01 +0000670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000671posix_do_stat(PyObject *self, PyObject *args, char *format,
672 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000673{
Fred Drake699f3522000-06-29 21:12:41 +0000674 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000675 char *path = NULL; /* pass this to stat; do not free() it */
676 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000677 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000678
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000679#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000680 int pathlen;
681 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000682#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000683
Tim Peters5aa91602002-01-30 05:46:57 +0000684 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000685 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000686 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000687 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000688
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000689#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000690 pathlen = strlen(path);
691 /* the library call can blow up if the file name is too long! */
692 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000693 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000694 errno = ENAMETOOLONG;
695 return posix_error();
696 }
697
Tim Peters500bd032001-12-19 19:05:01 +0000698 /* Remove trailing slash or backslash, unless it's the current
699 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
700 */
701 if (pathlen > 0 &&
702 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
703 /* It does end with a slash -- exempt the root drive cases. */
704 /* XXX UNC root drives should also be exempted? */
705 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
706 /* leave it alone */;
707 else {
708 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000709 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000710 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000711 path = pathcopy;
712 }
713 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000714#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000715
Barry Warsaw53699e91996-12-10 23:23:01 +0000716 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000717 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000718 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000719 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000720 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000721
Tim Peters500bd032001-12-19 19:05:01 +0000722 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000723 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724}
725
726
727/* POSIX methods */
728
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000729PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000730"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000731Use the real uid/gid to test for access to a path. Note that most\n\
732operations will use the effective uid/gid, therefore this routine can\n\
733be used in a suid/sgid environment to test if the invoking user has the\n\
734specified access to the path. The mode argument can be F_OK to test\n\
735existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000736
737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000738posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000739{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000740 char *path;
741 int mode;
742 int res;
743
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000744 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000745 return NULL;
746 Py_BEGIN_ALLOW_THREADS
747 res = access(path, mode);
748 Py_END_ALLOW_THREADS
749 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000750}
751
Guido van Rossumd371ff11999-01-25 16:12:23 +0000752#ifndef F_OK
753#define F_OK 0
754#endif
755#ifndef R_OK
756#define R_OK 4
757#endif
758#ifndef W_OK
759#define W_OK 2
760#endif
761#ifndef X_OK
762#define X_OK 1
763#endif
764
765#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000766PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000767"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000768Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000769
770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000771posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000772{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000773 int id;
774 char *ret;
775
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000776 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000777 return NULL;
778
Guido van Rossum94f6f721999-01-06 18:42:14 +0000779 ret = ttyname(id);
780 if (ret == NULL)
781 return(posix_error());
782 return(PyString_FromString(ret));
783}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000784#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000785
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000786#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000787PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000788"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000789Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000790
791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000792posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000793{
794 char *ret;
795 char buffer[L_ctermid];
796
797 if (!PyArg_ParseTuple(args, ":ctermid"))
798 return NULL;
799
Greg Wardb48bc172000-03-01 21:51:56 +0000800#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000801 ret = ctermid_r(buffer);
802#else
803 ret = ctermid(buffer);
804#endif
805 if (ret == NULL)
806 return(posix_error());
807 return(PyString_FromString(buffer));
808}
809#endif
810
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000811PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000812"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000813Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000814
Barry Warsaw53699e91996-12-10 23:23:01 +0000815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000816posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000817{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000818#if defined(PYOS_OS2) && defined(PYCC_GCC)
819 return posix_1str(args, "et:chdir", _chdir2);
820#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000821 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000822#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000823}
824
Fred Drake4d1e64b2002-04-15 19:40:07 +0000825#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000826PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000827"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +0000828Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000829opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +0000830
831static PyObject *
832posix_fchdir(PyObject *self, PyObject *fdobj)
833{
834 return posix_fildes(fdobj, fchdir);
835}
836#endif /* HAVE_FCHDIR */
837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000839PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000840"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000841Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000842
Barry Warsaw53699e91996-12-10 23:23:01 +0000843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000844posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000845{
Mark Hammondef8b6542001-05-13 08:04:26 +0000846 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000847 int i;
848 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000849 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000850 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000851 return NULL;
852 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000853 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000854 Py_END_ALLOW_THREADS
855 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000856 return posix_error_with_allocated_filename(path);
857 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000858 Py_INCREF(Py_None);
859 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000860}
861
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000862
Martin v. Löwis244edc82001-10-04 22:44:26 +0000863#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000864PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000865"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000866Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +0000867
868static PyObject *
869posix_chroot(PyObject *self, PyObject *args)
870{
871 return posix_1str(args, "et:chroot", chroot);
872}
873#endif
874
Guido van Rossum21142a01999-01-08 21:05:37 +0000875#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000876PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000877"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000878force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000879
880static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000881posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000882{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000883 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000884}
885#endif /* HAVE_FSYNC */
886
887#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000888
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000889#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000890extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
891#endif
892
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000893PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000894"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +0000895force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000896 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000897
898static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000899posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000900{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000901 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000902}
903#endif /* HAVE_FDATASYNC */
904
905
Fredrik Lundh10723342000-07-10 16:38:09 +0000906#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000907PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000908"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000909Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000910
Barry Warsaw53699e91996-12-10 23:23:01 +0000911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000912posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000913{
Mark Hammondef8b6542001-05-13 08:04:26 +0000914 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000915 int uid, gid;
916 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000917 if (!PyArg_ParseTuple(args, "etii:chown",
918 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000919 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000920 return NULL;
921 Py_BEGIN_ALLOW_THREADS
922 res = chown(path, (uid_t) uid, (gid_t) gid);
923 Py_END_ALLOW_THREADS
924 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000925 return posix_error_with_allocated_filename(path);
926 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000927 Py_INCREF(Py_None);
928 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000929}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000930#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000931
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000932
Guido van Rossum36bc6801995-06-14 22:54:23 +0000933#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000934PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000935"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000936Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000937
Barry Warsaw53699e91996-12-10 23:23:01 +0000938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000939posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000940{
941 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000942 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000943 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000944 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000945 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000946#if defined(PYOS_OS2) && defined(PYCC_GCC)
947 res = _getcwd2(buf, sizeof buf);
948#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000949 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000950#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000951 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000952 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000953 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000954 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000955}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000956#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000958
Guido van Rossumb6775db1994-08-01 11:34:53 +0000959#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000960PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000961"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000962Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000963
Barry Warsaw53699e91996-12-10 23:23:01 +0000964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000965posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000966{
Mark Hammondef8b6542001-05-13 08:04:26 +0000967 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000968}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000969#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000970
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000971
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000972PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000973"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000974Return a list containing the names of the entries in the directory.\n\
975\n\
976 path: path of directory to list\n\
977\n\
978The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000979entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000980
Barry Warsaw53699e91996-12-10 23:23:01 +0000981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000982posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000983{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000984 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000985 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000986#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000987
Barry Warsaw53699e91996-12-10 23:23:01 +0000988 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000989 HANDLE hFindFile;
990 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000991 /* MAX_PATH characters could mean a bigger encoded string */
992 char namebuf[MAX_PATH*2+5];
993 char *bufptr = namebuf;
994 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000995
Tim Peters5aa91602002-01-30 05:46:57 +0000996 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +0000997 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000998 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +0000999 if (len > 0) {
1000 char ch = namebuf[len-1];
1001 if (ch != SEP && ch != ALTSEP && ch != ':')
1002 namebuf[len++] = '/';
1003 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001004 strcpy(namebuf + len, "*.*");
1005
Barry Warsaw53699e91996-12-10 23:23:01 +00001006 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001007 return NULL;
1008
1009 hFindFile = FindFirstFile(namebuf, &FileData);
1010 if (hFindFile == INVALID_HANDLE_VALUE) {
1011 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001012 if (errno == ERROR_FILE_NOT_FOUND)
1013 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001014 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001015 }
1016 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001017 if (FileData.cFileName[0] == '.' &&
1018 (FileData.cFileName[1] == '\0' ||
1019 FileData.cFileName[1] == '.' &&
1020 FileData.cFileName[2] == '\0'))
1021 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001022 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001023 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001024 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001025 d = NULL;
1026 break;
1027 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001028 if (PyList_Append(d, v) != 0) {
1029 Py_DECREF(v);
1030 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001031 d = NULL;
1032 break;
1033 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001034 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001035 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1036
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001037 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001038 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001039
1040 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001041
Tim Peters0bb44a42000-09-15 07:44:49 +00001042#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001043
1044#ifndef MAX_PATH
1045#define MAX_PATH CCHMAXPATH
1046#endif
1047 char *name, *pt;
1048 int len;
1049 PyObject *d, *v;
1050 char namebuf[MAX_PATH+5];
1051 HDIR hdir = 1;
1052 ULONG srchcnt = 1;
1053 FILEFINDBUF3 ep;
1054 APIRET rc;
1055
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001056 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001057 return NULL;
1058 if (len >= MAX_PATH) {
1059 PyErr_SetString(PyExc_ValueError, "path too long");
1060 return NULL;
1061 }
1062 strcpy(namebuf, name);
1063 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001064 if (*pt == ALTSEP)
1065 *pt = SEP;
1066 if (namebuf[len-1] != SEP)
1067 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001068 strcpy(namebuf + len, "*.*");
1069
1070 if ((d = PyList_New(0)) == NULL)
1071 return NULL;
1072
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001073 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1074 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001075 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001076 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1077 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1078 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001079
1080 if (rc != NO_ERROR) {
1081 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001082 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001083 }
1084
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001085 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001086 do {
1087 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001088 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001089 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001090
1091 strcpy(namebuf, ep.achName);
1092
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001093 /* Leave Case of Name Alone -- In Native Form */
1094 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001095
1096 v = PyString_FromString(namebuf);
1097 if (v == NULL) {
1098 Py_DECREF(d);
1099 d = NULL;
1100 break;
1101 }
1102 if (PyList_Append(d, v) != 0) {
1103 Py_DECREF(v);
1104 Py_DECREF(d);
1105 d = NULL;
1106 break;
1107 }
1108 Py_DECREF(v);
1109 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1110 }
1111
1112 return d;
1113#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001114
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001115 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001116 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001117 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001118 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001119 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001120 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001121 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001122 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001123 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001124 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001125 closedir(dirp);
1126 return NULL;
1127 }
1128 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001129 if (ep->d_name[0] == '.' &&
1130 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001131 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001132 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001133 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001134 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001135 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001136 d = NULL;
1137 break;
1138 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001139 if (PyList_Append(d, v) != 0) {
1140 Py_DECREF(v);
1141 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142 d = NULL;
1143 break;
1144 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001145 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001146 }
1147 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001148
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001149 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001150
Tim Peters0bb44a42000-09-15 07:44:49 +00001151#endif /* which OS */
1152} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001154#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001155/* A helper function for abspath on win32 */
1156static PyObject *
1157posix__getfullpathname(PyObject *self, PyObject *args)
1158{
1159 /* assume encoded strings wont more than double no of chars */
1160 char inbuf[MAX_PATH*2];
1161 char *inbufp = inbuf;
1162 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1163 char outbuf[MAX_PATH*2];
1164 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001165 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1166 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001167 &insize))
1168 return NULL;
1169 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1170 outbuf, &temp))
1171 return win32_error("GetFullPathName", inbuf);
1172 return PyString_FromString(outbuf);
1173} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001174#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001175
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001176PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001177"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001178Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001179
Barry Warsaw53699e91996-12-10 23:23:01 +00001180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001181posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001183 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001184 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001185 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001186 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001187 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001188 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001189 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001190#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001191 res = mkdir(path);
1192#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001193 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001194#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001195 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001196 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001197 return posix_error_with_allocated_filename(path);
1198 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001199 Py_INCREF(Py_None);
1200 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001201}
1202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001203
Guido van Rossumb6775db1994-08-01 11:34:53 +00001204#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001205#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1206#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1207#include <sys/resource.h>
1208#endif
1209#endif
1210
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001211PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001212"nice(inc) -> new_priority\n\n\
1213Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001214
Barry Warsaw53699e91996-12-10 23:23:01 +00001215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001216posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001217{
1218 int increment, value;
1219
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001220 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001221 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001222
1223 /* There are two flavours of 'nice': one that returns the new
1224 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001225 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1226 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001227
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001228 If we are of the nice family that returns the new priority, we
1229 need to clear errno before the call, and check if errno is filled
1230 before calling posix_error() on a returnvalue of -1, because the
1231 -1 may be the actual new priority! */
1232
1233 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001234 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001235#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001236 if (value == 0)
1237 value = getpriority(PRIO_PROCESS, 0);
1238#endif
1239 if (value == -1 && errno != 0)
1240 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001241 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001242 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001243}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001244#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001246
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001247PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001248"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001249Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001250
Barry Warsaw53699e91996-12-10 23:23:01 +00001251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001252posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001253{
Mark Hammondef8b6542001-05-13 08:04:26 +00001254 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001255}
1256
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001257
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001258PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001259"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001260Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001261
Barry Warsaw53699e91996-12-10 23:23:01 +00001262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001263posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001264{
Mark Hammondef8b6542001-05-13 08:04:26 +00001265 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001266}
1267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001268
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001269PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001270"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001271Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001272
Barry Warsaw53699e91996-12-10 23:23:01 +00001273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001274posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275{
Mark Hammondef8b6542001-05-13 08:04:26 +00001276 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001277}
1278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001279
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001280#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001281PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001282"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001283Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001284
Barry Warsaw53699e91996-12-10 23:23:01 +00001285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001286posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001287{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001288 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001289 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001290 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001291 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001292 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001293 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001294 Py_END_ALLOW_THREADS
1295 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001296}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001297#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001298
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001299
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001300PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001301"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001302Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001303
Barry Warsaw53699e91996-12-10 23:23:01 +00001304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001305posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306{
1307 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001308 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001309 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001310 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001311 if (i < 0)
1312 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001313 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314}
1315
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001316
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001317PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001318"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001319Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001320
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001321PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001322"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001323Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001324
Barry Warsaw53699e91996-12-10 23:23:01 +00001325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001326posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001327{
Mark Hammondef8b6542001-05-13 08:04:26 +00001328 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001329}
1330
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001331
Guido van Rossumb6775db1994-08-01 11:34:53 +00001332#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001333PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001334"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001335Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001336
Barry Warsaw53699e91996-12-10 23:23:01 +00001337static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001338posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001339{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001340 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001341 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001342 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001343 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001344 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001345 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001346 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001347 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001349 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001350 u.sysname,
1351 u.nodename,
1352 u.release,
1353 u.version,
1354 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001355}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001356#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001358
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001359PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001360"utime(path, (atime, utime))\n\
1361utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001362Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001363second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001364
Barry Warsaw53699e91996-12-10 23:23:01 +00001365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001366posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001367{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001368 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001369 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001370 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001371 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001372
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001373/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001374#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001375 struct utimbuf buf;
1376#define ATIME buf.actime
1377#define MTIME buf.modtime
1378#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001379#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001380 time_t buf[2];
1381#define ATIME buf[0]
1382#define MTIME buf[1]
1383#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001384#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001385
Barry Warsaw3cef8562000-05-01 16:17:24 +00001386 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001387 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001388 if (arg == Py_None) {
1389 /* optional time values not given */
1390 Py_BEGIN_ALLOW_THREADS
1391 res = utime(path, NULL);
1392 Py_END_ALLOW_THREADS
1393 }
1394 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1395 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001396 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001397 return NULL;
1398 }
1399 else {
1400 ATIME = atime;
1401 MTIME = mtime;
1402 Py_BEGIN_ALLOW_THREADS
1403 res = utime(path, UTIME_ARG);
1404 Py_END_ALLOW_THREADS
1405 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001406 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001407 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001408 Py_INCREF(Py_None);
1409 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001410#undef UTIME_ARG
1411#undef ATIME
1412#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001413}
1414
Guido van Rossum85e3b011991-06-03 12:42:10 +00001415
Guido van Rossum3b066191991-06-04 19:40:25 +00001416/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001417
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001418PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001419"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001420Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001421
Barry Warsaw53699e91996-12-10 23:23:01 +00001422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001423posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001424{
1425 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001426 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001427 return NULL;
1428 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001429 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001430}
1431
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001432
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001433#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001434PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001435"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001436Execute an executable path with arguments, replacing current process.\n\
1437\n\
1438 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001439 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001440
Barry Warsaw53699e91996-12-10 23:23:01 +00001441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001442posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001443{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001444 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001445 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001446 char **argvlist;
1447 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001448 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001449
Guido van Rossum89b33251993-10-22 14:26:06 +00001450 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001451 argv is a list or tuple of strings. */
1452
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001453 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001454 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001455 if (PyList_Check(argv)) {
1456 argc = PyList_Size(argv);
1457 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001458 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001459 else if (PyTuple_Check(argv)) {
1460 argc = PyTuple_Size(argv);
1461 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001462 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001463 else {
Fred Drake661ea262000-10-24 19:57:45 +00001464 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001465 return NULL;
1466 }
1467
1468 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001469 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001470 return NULL;
1471 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001472
Barry Warsaw53699e91996-12-10 23:23:01 +00001473 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001474 if (argvlist == NULL)
1475 return NULL;
1476 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001477 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1478 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001479 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001480 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001481 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001482
Guido van Rossum85e3b011991-06-03 12:42:10 +00001483 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001484 }
1485 argvlist[argc] = NULL;
1486
Guido van Rossumb6775db1994-08-01 11:34:53 +00001487#ifdef BAD_EXEC_PROTOTYPES
1488 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001489#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001490 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001491#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001492
Guido van Rossum85e3b011991-06-03 12:42:10 +00001493 /* If we get here it's definitely an error */
1494
Barry Warsaw53699e91996-12-10 23:23:01 +00001495 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001496 return posix_error();
1497}
1498
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001499
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001500PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001501"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001502Execute a path with arguments and environment, replacing current process.\n\
1503\n\
1504 path: path of executable file\n\
1505 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001506 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001507
Barry Warsaw53699e91996-12-10 23:23:01 +00001508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001509posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001510{
1511 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001512 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001513 char **argvlist;
1514 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001515 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001516 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001517 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001518
1519 /* execve has three arguments: (path, argv, env), where
1520 argv is a list or tuple of strings and env is a dictionary
1521 like posix.environ. */
1522
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001523 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001524 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001525 if (PyList_Check(argv)) {
1526 argc = PyList_Size(argv);
1527 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001528 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001529 else if (PyTuple_Check(argv)) {
1530 argc = PyTuple_Size(argv);
1531 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001532 }
1533 else {
Fred Drake661ea262000-10-24 19:57:45 +00001534 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001535 return NULL;
1536 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001537 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001538 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001539 return NULL;
1540 }
1541
Guido van Rossum50422b42000-04-26 20:34:28 +00001542 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001543 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001544 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001545 return NULL;
1546 }
1547
Barry Warsaw53699e91996-12-10 23:23:01 +00001548 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001549 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001550 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001551 return NULL;
1552 }
1553 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001554 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001555 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001556 &argvlist[i]))
1557 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001558 goto fail_1;
1559 }
1560 }
1561 argvlist[argc] = NULL;
1562
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001563 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001564 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001565 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001566 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001567 goto fail_1;
1568 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001569 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001570 keys = PyMapping_Keys(env);
1571 vals = PyMapping_Values(env);
1572 if (!keys || !vals)
1573 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001574
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001575 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001576 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001577 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001578
1579 key = PyList_GetItem(keys, pos);
1580 val = PyList_GetItem(vals, pos);
1581 if (!key || !val)
1582 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001583
Fred Drake661ea262000-10-24 19:57:45 +00001584 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1585 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001586 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001587 goto fail_2;
1588 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001589
1590#if defined(PYOS_OS2)
1591 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1592 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1593#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001594 len = PyString_Size(key) + PyString_Size(val) + 2;
1595 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001596 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001597 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001598 goto fail_2;
1599 }
Tim Petersc8996f52001-12-03 20:41:00 +00001600 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001602#if defined(PYOS_OS2)
1603 }
1604#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001605 }
1606 envlist[envc] = 0;
1607
Guido van Rossumb6775db1994-08-01 11:34:53 +00001608
1609#ifdef BAD_EXEC_PROTOTYPES
1610 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001611#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001612 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001613#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001614
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001615 /* If we get here it's definitely an error */
1616
1617 (void) posix_error();
1618
1619 fail_2:
1620 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001621 PyMem_DEL(envlist[envc]);
1622 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001623 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001624 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001625 Py_XDECREF(vals);
1626 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001627 return NULL;
1628}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001629#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001631
Guido van Rossuma1065681999-01-25 23:20:23 +00001632#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001633PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001634"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001635Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001636\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001637 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001638 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001639 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001640
1641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001642posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001643{
1644 char *path;
1645 PyObject *argv;
1646 char **argvlist;
1647 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001648 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001649 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001650
1651 /* spawnv has three arguments: (mode, path, argv), where
1652 argv is a list or tuple of strings. */
1653
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001654 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001655 return NULL;
1656 if (PyList_Check(argv)) {
1657 argc = PyList_Size(argv);
1658 getitem = PyList_GetItem;
1659 }
1660 else if (PyTuple_Check(argv)) {
1661 argc = PyTuple_Size(argv);
1662 getitem = PyTuple_GetItem;
1663 }
1664 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001665 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001666 return NULL;
1667 }
1668
1669 argvlist = PyMem_NEW(char *, argc+1);
1670 if (argvlist == NULL)
1671 return NULL;
1672 for (i = 0; i < argc; i++) {
1673 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1674 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001675 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001676 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001677 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001678 }
1679 }
1680 argvlist[argc] = NULL;
1681
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001682#if defined(PYOS_OS2) && defined(PYCC_GCC)
1683 Py_BEGIN_ALLOW_THREADS
1684 spawnval = spawnv(mode, path, argvlist);
1685 Py_END_ALLOW_THREADS
1686#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001687 if (mode == _OLD_P_OVERLAY)
1688 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001689
Tim Peters25059d32001-12-07 20:35:43 +00001690 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001691 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001692 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001693#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001694
Guido van Rossuma1065681999-01-25 23:20:23 +00001695 PyMem_DEL(argvlist);
1696
Fred Drake699f3522000-06-29 21:12:41 +00001697 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001698 return posix_error();
1699 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001700#if SIZEOF_LONG == SIZEOF_VOID_P
1701 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001702#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001703 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001704#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001705}
1706
1707
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001708PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001709"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001710Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001711\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001712 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001713 path: path of executable file\n\
1714 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001715 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001716
1717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001718posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001719{
1720 char *path;
1721 PyObject *argv, *env;
1722 char **argvlist;
1723 char **envlist;
1724 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1725 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001726 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001727 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001728
1729 /* spawnve has four arguments: (mode, path, argv, env), where
1730 argv is a list or tuple of strings and env is a dictionary
1731 like posix.environ. */
1732
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001733 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001734 return NULL;
1735 if (PyList_Check(argv)) {
1736 argc = PyList_Size(argv);
1737 getitem = PyList_GetItem;
1738 }
1739 else if (PyTuple_Check(argv)) {
1740 argc = PyTuple_Size(argv);
1741 getitem = PyTuple_GetItem;
1742 }
1743 else {
Fred Drake661ea262000-10-24 19:57:45 +00001744 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001745 return NULL;
1746 }
1747 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001748 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001749 return NULL;
1750 }
1751
1752 argvlist = PyMem_NEW(char *, argc+1);
1753 if (argvlist == NULL) {
1754 PyErr_NoMemory();
1755 return NULL;
1756 }
1757 for (i = 0; i < argc; i++) {
1758 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001759 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001760 &argvlist[i]))
1761 {
1762 goto fail_1;
1763 }
1764 }
1765 argvlist[argc] = NULL;
1766
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001767 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001768 envlist = PyMem_NEW(char *, i + 1);
1769 if (envlist == NULL) {
1770 PyErr_NoMemory();
1771 goto fail_1;
1772 }
1773 envc = 0;
1774 keys = PyMapping_Keys(env);
1775 vals = PyMapping_Values(env);
1776 if (!keys || !vals)
1777 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001778
Guido van Rossuma1065681999-01-25 23:20:23 +00001779 for (pos = 0; pos < i; pos++) {
1780 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001781 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001782
1783 key = PyList_GetItem(keys, pos);
1784 val = PyList_GetItem(vals, pos);
1785 if (!key || !val)
1786 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001787
Fred Drake661ea262000-10-24 19:57:45 +00001788 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1789 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001790 {
1791 goto fail_2;
1792 }
Tim Petersc8996f52001-12-03 20:41:00 +00001793 len = PyString_Size(key) + PyString_Size(val) + 2;
1794 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001795 if (p == NULL) {
1796 PyErr_NoMemory();
1797 goto fail_2;
1798 }
Tim Petersc8996f52001-12-03 20:41:00 +00001799 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001800 envlist[envc++] = p;
1801 }
1802 envlist[envc] = 0;
1803
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001804#if defined(PYOS_OS2) && defined(PYCC_GCC)
1805 Py_BEGIN_ALLOW_THREADS
1806 spawnval = spawnve(mode, path, argvlist, envlist);
1807 Py_END_ALLOW_THREADS
1808#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001809 if (mode == _OLD_P_OVERLAY)
1810 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001811
1812 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001813 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001814 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001815#endif
Tim Peters25059d32001-12-07 20:35:43 +00001816
Fred Drake699f3522000-06-29 21:12:41 +00001817 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001818 (void) posix_error();
1819 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001820#if SIZEOF_LONG == SIZEOF_VOID_P
1821 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001822#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001823 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001824#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001825
1826 fail_2:
1827 while (--envc >= 0)
1828 PyMem_DEL(envlist[envc]);
1829 PyMem_DEL(envlist);
1830 fail_1:
1831 PyMem_DEL(argvlist);
1832 Py_XDECREF(vals);
1833 Py_XDECREF(keys);
1834 return res;
1835}
1836#endif /* HAVE_SPAWNV */
1837
1838
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001839#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001840PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001841"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001842Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1843\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001844Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001845
1846static PyObject *
1847posix_fork1(self, args)
1848 PyObject *self;
1849 PyObject *args;
1850{
1851 int pid;
1852 if (!PyArg_ParseTuple(args, ":fork1"))
1853 return NULL;
1854 pid = fork1();
1855 if (pid == -1)
1856 return posix_error();
1857 PyOS_AfterFork();
1858 return PyInt_FromLong((long)pid);
1859}
1860#endif
1861
1862
Guido van Rossumad0ee831995-03-01 10:34:45 +00001863#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001864PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001865"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001866Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001867Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001868
Barry Warsaw53699e91996-12-10 23:23:01 +00001869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001870posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001871{
1872 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001873 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001874 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001875 pid = fork();
1876 if (pid == -1)
1877 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001878 if (pid == 0)
1879 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001880 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001881}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001882#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001883
Fred Drake8cef4cf2000-06-28 16:40:38 +00001884#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1885#ifdef HAVE_PTY_H
1886#include <pty.h>
1887#else
1888#ifdef HAVE_LIBUTIL_H
1889#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001890#endif /* HAVE_LIBUTIL_H */
1891#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001892#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001893
Thomas Wouters70c21a12000-07-14 14:28:33 +00001894#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001895PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001896"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001897Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001898
1899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001900posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001901{
1902 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001903#ifndef HAVE_OPENPTY
1904 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001905#endif
1906
Fred Drake8cef4cf2000-06-28 16:40:38 +00001907 if (!PyArg_ParseTuple(args, ":openpty"))
1908 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001909
1910#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001911 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1912 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001913#else
1914 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1915 if (slave_name == NULL)
1916 return posix_error();
1917
1918 slave_fd = open(slave_name, O_RDWR);
1919 if (slave_fd < 0)
1920 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001921#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001922
Fred Drake8cef4cf2000-06-28 16:40:38 +00001923 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001924
Fred Drake8cef4cf2000-06-28 16:40:38 +00001925}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001926#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001927
1928#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001929PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001930"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00001931Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1932Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001933To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001934
1935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001936posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001937{
1938 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00001939
Fred Drake8cef4cf2000-06-28 16:40:38 +00001940 if (!PyArg_ParseTuple(args, ":forkpty"))
1941 return NULL;
1942 pid = forkpty(&master_fd, NULL, NULL, NULL);
1943 if (pid == -1)
1944 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001945 if (pid == 0)
1946 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001947 return Py_BuildValue("(ii)", pid, master_fd);
1948}
1949#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001950
Guido van Rossumad0ee831995-03-01 10:34:45 +00001951#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001952PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001953"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001954Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001955
Barry Warsaw53699e91996-12-10 23:23:01 +00001956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001957posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001958{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001959 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001960 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001961 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001962}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001963#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001964
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001965
Guido van Rossumad0ee831995-03-01 10:34:45 +00001966#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001967PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001968"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001969Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001970
Barry Warsaw53699e91996-12-10 23:23:01 +00001971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001972posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001973{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001974 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001975 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001976 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001977}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001978#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001979
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001980
Guido van Rossumad0ee831995-03-01 10:34:45 +00001981#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001982PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001983"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001984Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001985
Barry Warsaw53699e91996-12-10 23:23:01 +00001986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001987posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001988{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001989 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001990 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001991 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001992}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001993#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001994
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001996PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001997"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001998Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001999
Barry Warsaw53699e91996-12-10 23:23:01 +00002000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002001posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002002{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002003 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002004 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002005 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002006}
2007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002008
Fred Drakec9680921999-12-13 16:37:25 +00002009#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002010PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002011"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002012Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002013
2014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002015posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002016{
2017 PyObject *result = NULL;
2018
2019 if (PyArg_ParseTuple(args, ":getgroups")) {
2020#ifdef NGROUPS_MAX
2021#define MAX_GROUPS NGROUPS_MAX
2022#else
2023 /* defined to be 16 on Solaris7, so this should be a small number */
2024#define MAX_GROUPS 64
2025#endif
2026 gid_t grouplist[MAX_GROUPS];
2027 int n;
2028
2029 n = getgroups(MAX_GROUPS, grouplist);
2030 if (n < 0)
2031 posix_error();
2032 else {
2033 result = PyList_New(n);
2034 if (result != NULL) {
2035 PyObject *o;
2036 int i;
2037 for (i = 0; i < n; ++i) {
2038 o = PyInt_FromLong((long)grouplist[i]);
2039 if (o == NULL) {
2040 Py_DECREF(result);
2041 result = NULL;
2042 break;
2043 }
2044 PyList_SET_ITEM(result, i, o);
2045 }
2046 }
2047 }
2048 }
2049 return result;
2050}
2051#endif
2052
Martin v. Löwis606edc12002-06-13 21:09:11 +00002053#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002054PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002055"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002056Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002057
2058static PyObject *
2059posix_getpgid(PyObject *self, PyObject *args)
2060{
2061 int pid, pgid;
2062 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2063 return NULL;
2064 pgid = getpgid(pid);
2065 if (pgid < 0)
2066 return posix_error();
2067 return PyInt_FromLong((long)pgid);
2068}
2069#endif /* HAVE_GETPGID */
2070
2071
Guido van Rossumb6775db1994-08-01 11:34:53 +00002072#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002074"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002075Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002076
Barry Warsaw53699e91996-12-10 23:23:01 +00002077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002078posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002079{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002080 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002081 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002082#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002083 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002084#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002085 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002086#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002087}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002088#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002090
Guido van Rossumb6775db1994-08-01 11:34:53 +00002091#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002092PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002093"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002094Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002095
Barry Warsaw53699e91996-12-10 23:23:01 +00002096static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002097posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002098{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002099 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002100 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002101#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002102 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002103#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002104 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002105#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002106 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002107 Py_INCREF(Py_None);
2108 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002109}
2110
Guido van Rossumb6775db1994-08-01 11:34:53 +00002111#endif /* HAVE_SETPGRP */
2112
Guido van Rossumad0ee831995-03-01 10:34:45 +00002113#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002114PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002115"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002116Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002117
Barry Warsaw53699e91996-12-10 23:23:01 +00002118static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002119posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002120{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002121 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002122 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002123 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002124}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002125#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002127
Fred Drake12c6e2d1999-12-14 21:25:03 +00002128#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002129PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002130"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002131Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002132
2133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002134posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002135{
2136 PyObject *result = NULL;
2137
2138 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002139 char *name;
2140 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002141
Fred Drakea30680b2000-12-06 21:24:28 +00002142 errno = 0;
2143 name = getlogin();
2144 if (name == NULL) {
2145 if (errno)
2146 posix_error();
2147 else
2148 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002149 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002150 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002151 else
2152 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002153 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002154 }
2155 return result;
2156}
2157#endif
2158
Guido van Rossumad0ee831995-03-01 10:34:45 +00002159#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002160PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002161"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002162Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002163
Barry Warsaw53699e91996-12-10 23:23:01 +00002164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002165posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002166{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002167 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002168 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002169 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002170}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002171#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002172
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002173
Guido van Rossumad0ee831995-03-01 10:34:45 +00002174#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002175PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002176"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002177Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002178
Barry Warsaw53699e91996-12-10 23:23:01 +00002179static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002180posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002181{
2182 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002183 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002184 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002185#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002186 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2187 APIRET rc;
2188 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002189 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002190
2191 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2192 APIRET rc;
2193 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002194 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002195
2196 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002197 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002198#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002199 if (kill(pid, sig) == -1)
2200 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002201#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002202 Py_INCREF(Py_None);
2203 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002204}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002205#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002206
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002207#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002208PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002209"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002210Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002211
2212static PyObject *
2213posix_killpg(PyObject *self, PyObject *args)
2214{
2215 int pgid, sig;
2216 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2217 return NULL;
2218 if (killpg(pgid, sig) == -1)
2219 return posix_error();
2220 Py_INCREF(Py_None);
2221 return Py_None;
2222}
2223#endif
2224
Guido van Rossumc0125471996-06-28 18:55:32 +00002225#ifdef HAVE_PLOCK
2226
2227#ifdef HAVE_SYS_LOCK_H
2228#include <sys/lock.h>
2229#endif
2230
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002231PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002232"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002233Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002234
Barry Warsaw53699e91996-12-10 23:23:01 +00002235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002236posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002237{
2238 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002239 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002240 return NULL;
2241 if (plock(op) == -1)
2242 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002243 Py_INCREF(Py_None);
2244 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002245}
2246#endif
2247
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002248
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002249#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002250PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002251"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002252Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002253
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002254#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002255#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002256static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002257async_system(const char *command)
2258{
2259 char *p, errormsg[256], args[1024];
2260 RESULTCODES rcodes;
2261 APIRET rc;
2262 char *shell = getenv("COMSPEC");
2263 if (!shell)
2264 shell = "cmd";
2265
2266 strcpy(args, shell);
2267 p = &args[ strlen(args)+1 ];
2268 strcpy(p, "/c ");
2269 strcat(p, command);
2270 p += strlen(p) + 1;
2271 *p = '\0';
2272
2273 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002274 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002275 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002276 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002277 &rcodes, shell);
2278 return rc;
2279}
2280
Guido van Rossumd48f2521997-12-05 22:19:34 +00002281static FILE *
2282popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283{
2284 HFILE rhan, whan;
2285 FILE *retfd = NULL;
2286 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2287
Guido van Rossumd48f2521997-12-05 22:19:34 +00002288 if (rc != NO_ERROR) {
2289 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002290 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002291 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002292
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002293 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2294 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002295
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002296 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2297 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002298
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002299 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2300 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002301
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002302 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002303 }
2304
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002305 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2306 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002307
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002308 if (rc == NO_ERROR)
2309 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2310
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002311 close(oldfd); /* And Close Saved STDOUT Handle */
2312 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002313
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002314 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2315 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002316
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002317 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2318 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002319
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002320 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2321 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002322
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002323 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002324 }
2325
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002326 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2327 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002328
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002329 if (rc == NO_ERROR)
2330 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2331
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002332 close(oldfd); /* And Close Saved STDIN Handle */
2333 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002334
Guido van Rossumd48f2521997-12-05 22:19:34 +00002335 } else {
2336 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002337 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002338 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002339}
2340
2341static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002342posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002343{
2344 char *name;
2345 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002346 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002347 FILE *fp;
2348 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002349 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002350 return NULL;
2351 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002352 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002353 Py_END_ALLOW_THREADS
2354 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002355 return os2_error(err);
2356
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002357 f = PyFile_FromFile(fp, name, mode, fclose);
2358 if (f != NULL)
2359 PyFile_SetBufSize(f, bufsize);
2360 return f;
2361}
2362
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002363#elif defined(PYCC_GCC)
2364
2365/* standard posix version of popen() support */
2366static PyObject *
2367posix_popen(PyObject *self, PyObject *args)
2368{
2369 char *name;
2370 char *mode = "r";
2371 int bufsize = -1;
2372 FILE *fp;
2373 PyObject *f;
2374 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2375 return NULL;
2376 Py_BEGIN_ALLOW_THREADS
2377 fp = popen(name, mode);
2378 Py_END_ALLOW_THREADS
2379 if (fp == NULL)
2380 return posix_error();
2381 f = PyFile_FromFile(fp, name, mode, pclose);
2382 if (f != NULL)
2383 PyFile_SetBufSize(f, bufsize);
2384 return f;
2385}
2386
2387/* fork() under OS/2 has lots'o'warts
2388 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2389 * most of this code is a ripoff of the win32 code, but using the
2390 * capabilities of EMX's C library routines
2391 */
2392
2393/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2394#define POPEN_1 1
2395#define POPEN_2 2
2396#define POPEN_3 3
2397#define POPEN_4 4
2398
2399static PyObject *_PyPopen(char *, int, int, int);
2400static int _PyPclose(FILE *file);
2401
2402/*
2403 * Internal dictionary mapping popen* file pointers to process handles,
2404 * for use when retrieving the process exit code. See _PyPclose() below
2405 * for more information on this dictionary's use.
2406 */
2407static PyObject *_PyPopenProcs = NULL;
2408
2409/* os2emx version of popen2()
2410 *
2411 * The result of this function is a pipe (file) connected to the
2412 * process's stdin, and a pipe connected to the process's stdout.
2413 */
2414
2415static PyObject *
2416os2emx_popen2(PyObject *self, PyObject *args)
2417{
2418 PyObject *f;
2419 int tm=0;
2420
2421 char *cmdstring;
2422 char *mode = "t";
2423 int bufsize = -1;
2424 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2425 return NULL;
2426
2427 if (*mode == 't')
2428 tm = O_TEXT;
2429 else if (*mode != 'b') {
2430 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2431 return NULL;
2432 } else
2433 tm = O_BINARY;
2434
2435 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2436
2437 return f;
2438}
2439
2440/*
2441 * Variation on os2emx.popen2
2442 *
2443 * The result of this function is 3 pipes - the process's stdin,
2444 * stdout and stderr
2445 */
2446
2447static PyObject *
2448os2emx_popen3(PyObject *self, PyObject *args)
2449{
2450 PyObject *f;
2451 int tm = 0;
2452
2453 char *cmdstring;
2454 char *mode = "t";
2455 int bufsize = -1;
2456 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2457 return NULL;
2458
2459 if (*mode == 't')
2460 tm = O_TEXT;
2461 else if (*mode != 'b') {
2462 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2463 return NULL;
2464 } else
2465 tm = O_BINARY;
2466
2467 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2468
2469 return f;
2470}
2471
2472/*
2473 * Variation on os2emx.popen2
2474 *
2475 * The result of this function is 2 pipes - the processes stdin,
2476 * and stdout+stderr combined as a single pipe.
2477 */
2478
2479static PyObject *
2480os2emx_popen4(PyObject *self, PyObject *args)
2481{
2482 PyObject *f;
2483 int tm = 0;
2484
2485 char *cmdstring;
2486 char *mode = "t";
2487 int bufsize = -1;
2488 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2489 return NULL;
2490
2491 if (*mode == 't')
2492 tm = O_TEXT;
2493 else if (*mode != 'b') {
2494 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2495 return NULL;
2496 } else
2497 tm = O_BINARY;
2498
2499 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2500
2501 return f;
2502}
2503
2504/* a couple of structures for convenient handling of multiple
2505 * file handles and pipes
2506 */
2507struct file_ref
2508{
2509 int handle;
2510 int flags;
2511};
2512
2513struct pipe_ref
2514{
2515 int rd;
2516 int wr;
2517};
2518
2519/* The following code is derived from the win32 code */
2520
2521static PyObject *
2522_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2523{
2524 struct file_ref stdio[3];
2525 struct pipe_ref p_fd[3];
2526 FILE *p_s[3];
2527 int file_count, i, pipe_err, pipe_pid;
2528 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2529 PyObject *f, *p_f[3];
2530
2531 /* file modes for subsequent fdopen's on pipe handles */
2532 if (mode == O_TEXT)
2533 {
2534 rd_mode = "rt";
2535 wr_mode = "wt";
2536 }
2537 else
2538 {
2539 rd_mode = "rb";
2540 wr_mode = "wb";
2541 }
2542
2543 /* prepare shell references */
2544 if ((shell = getenv("EMXSHELL")) == NULL)
2545 if ((shell = getenv("COMSPEC")) == NULL)
2546 {
2547 errno = ENOENT;
2548 return posix_error();
2549 }
2550
2551 sh_name = _getname(shell);
2552 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2553 opt = "/c";
2554 else
2555 opt = "-c";
2556
2557 /* save current stdio fds + their flags, and set not inheritable */
2558 i = pipe_err = 0;
2559 while (pipe_err >= 0 && i < 3)
2560 {
2561 pipe_err = stdio[i].handle = dup(i);
2562 stdio[i].flags = fcntl(i, F_GETFD, 0);
2563 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2564 i++;
2565 }
2566 if (pipe_err < 0)
2567 {
2568 /* didn't get them all saved - clean up and bail out */
2569 int saved_err = errno;
2570 while (i-- > 0)
2571 {
2572 close(stdio[i].handle);
2573 }
2574 errno = saved_err;
2575 return posix_error();
2576 }
2577
2578 /* create pipe ends */
2579 file_count = 2;
2580 if (n == POPEN_3)
2581 file_count = 3;
2582 i = pipe_err = 0;
2583 while ((pipe_err == 0) && (i < file_count))
2584 pipe_err = pipe((int *)&p_fd[i++]);
2585 if (pipe_err < 0)
2586 {
2587 /* didn't get them all made - clean up and bail out */
2588 while (i-- > 0)
2589 {
2590 close(p_fd[i].wr);
2591 close(p_fd[i].rd);
2592 }
2593 errno = EPIPE;
2594 return posix_error();
2595 }
2596
2597 /* change the actual standard IO streams over temporarily,
2598 * making the retained pipe ends non-inheritable
2599 */
2600 pipe_err = 0;
2601
2602 /* - stdin */
2603 if (dup2(p_fd[0].rd, 0) == 0)
2604 {
2605 close(p_fd[0].rd);
2606 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2607 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2608 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2609 {
2610 close(p_fd[0].wr);
2611 pipe_err = -1;
2612 }
2613 }
2614 else
2615 {
2616 pipe_err = -1;
2617 }
2618
2619 /* - stdout */
2620 if (pipe_err == 0)
2621 {
2622 if (dup2(p_fd[1].wr, 1) == 1)
2623 {
2624 close(p_fd[1].wr);
2625 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2626 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2627 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2628 {
2629 close(p_fd[1].rd);
2630 pipe_err = -1;
2631 }
2632 }
2633 else
2634 {
2635 pipe_err = -1;
2636 }
2637 }
2638
2639 /* - stderr, as required */
2640 if (pipe_err == 0)
2641 switch (n)
2642 {
2643 case POPEN_3:
2644 {
2645 if (dup2(p_fd[2].wr, 2) == 2)
2646 {
2647 close(p_fd[2].wr);
2648 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2649 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2650 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2651 {
2652 close(p_fd[2].rd);
2653 pipe_err = -1;
2654 }
2655 }
2656 else
2657 {
2658 pipe_err = -1;
2659 }
2660 break;
2661 }
2662
2663 case POPEN_4:
2664 {
2665 if (dup2(1, 2) != 2)
2666 {
2667 pipe_err = -1;
2668 }
2669 break;
2670 }
2671 }
2672
2673 /* spawn the child process */
2674 if (pipe_err == 0)
2675 {
2676 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2677 if (pipe_pid == -1)
2678 {
2679 pipe_err = -1;
2680 }
2681 else
2682 {
2683 /* save the PID into the FILE structure
2684 * NOTE: this implementation doesn't actually
2685 * take advantage of this, but do it for
2686 * completeness - AIM Apr01
2687 */
2688 for (i = 0; i < file_count; i++)
2689 p_s[i]->_pid = pipe_pid;
2690 }
2691 }
2692
2693 /* reset standard IO to normal */
2694 for (i = 0; i < 3; i++)
2695 {
2696 dup2(stdio[i].handle, i);
2697 fcntl(i, F_SETFD, stdio[i].flags);
2698 close(stdio[i].handle);
2699 }
2700
2701 /* if any remnant problems, clean up and bail out */
2702 if (pipe_err < 0)
2703 {
2704 for (i = 0; i < 3; i++)
2705 {
2706 close(p_fd[i].rd);
2707 close(p_fd[i].wr);
2708 }
2709 errno = EPIPE;
2710 return posix_error_with_filename(cmdstring);
2711 }
2712
2713 /* build tuple of file objects to return */
2714 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2715 PyFile_SetBufSize(p_f[0], bufsize);
2716 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2717 PyFile_SetBufSize(p_f[1], bufsize);
2718 if (n == POPEN_3)
2719 {
2720 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2721 PyFile_SetBufSize(p_f[0], bufsize);
2722 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2723 }
2724 else
2725 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2726
2727 /*
2728 * Insert the files we've created into the process dictionary
2729 * all referencing the list with the process handle and the
2730 * initial number of files (see description below in _PyPclose).
2731 * Since if _PyPclose later tried to wait on a process when all
2732 * handles weren't closed, it could create a deadlock with the
2733 * child, we spend some energy here to try to ensure that we
2734 * either insert all file handles into the dictionary or none
2735 * at all. It's a little clumsy with the various popen modes
2736 * and variable number of files involved.
2737 */
2738 if (!_PyPopenProcs)
2739 {
2740 _PyPopenProcs = PyDict_New();
2741 }
2742
2743 if (_PyPopenProcs)
2744 {
2745 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2746 int ins_rc[3];
2747
2748 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2749 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2750
2751 procObj = PyList_New(2);
2752 pidObj = PyInt_FromLong((long) pipe_pid);
2753 intObj = PyInt_FromLong((long) file_count);
2754
2755 if (procObj && pidObj && intObj)
2756 {
2757 PyList_SetItem(procObj, 0, pidObj);
2758 PyList_SetItem(procObj, 1, intObj);
2759
2760 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2761 if (fileObj[0])
2762 {
2763 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2764 fileObj[0],
2765 procObj);
2766 }
2767 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2768 if (fileObj[1])
2769 {
2770 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2771 fileObj[1],
2772 procObj);
2773 }
2774 if (file_count >= 3)
2775 {
2776 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2777 if (fileObj[2])
2778 {
2779 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2780 fileObj[2],
2781 procObj);
2782 }
2783 }
2784
2785 if (ins_rc[0] < 0 || !fileObj[0] ||
2786 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2787 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2788 {
2789 /* Something failed - remove any dictionary
2790 * entries that did make it.
2791 */
2792 if (!ins_rc[0] && fileObj[0])
2793 {
2794 PyDict_DelItem(_PyPopenProcs,
2795 fileObj[0]);
2796 }
2797 if (!ins_rc[1] && fileObj[1])
2798 {
2799 PyDict_DelItem(_PyPopenProcs,
2800 fileObj[1]);
2801 }
2802 if (!ins_rc[2] && fileObj[2])
2803 {
2804 PyDict_DelItem(_PyPopenProcs,
2805 fileObj[2]);
2806 }
2807 }
2808 }
2809
2810 /*
2811 * Clean up our localized references for the dictionary keys
2812 * and value since PyDict_SetItem will Py_INCREF any copies
2813 * that got placed in the dictionary.
2814 */
2815 Py_XDECREF(procObj);
2816 Py_XDECREF(fileObj[0]);
2817 Py_XDECREF(fileObj[1]);
2818 Py_XDECREF(fileObj[2]);
2819 }
2820
2821 /* Child is launched. */
2822 return f;
2823}
2824
2825/*
2826 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2827 * exit code for the child process and return as a result of the close.
2828 *
2829 * This function uses the _PyPopenProcs dictionary in order to map the
2830 * input file pointer to information about the process that was
2831 * originally created by the popen* call that created the file pointer.
2832 * The dictionary uses the file pointer as a key (with one entry
2833 * inserted for each file returned by the original popen* call) and a
2834 * single list object as the value for all files from a single call.
2835 * The list object contains the Win32 process handle at [0], and a file
2836 * count at [1], which is initialized to the total number of file
2837 * handles using that list.
2838 *
2839 * This function closes whichever handle it is passed, and decrements
2840 * the file count in the dictionary for the process handle pointed to
2841 * by this file. On the last close (when the file count reaches zero),
2842 * this function will wait for the child process and then return its
2843 * exit code as the result of the close() operation. This permits the
2844 * files to be closed in any order - it is always the close() of the
2845 * final handle that will return the exit code.
2846 */
2847
2848 /* RED_FLAG 31-Aug-2000 Tim
2849 * This is always called (today!) between a pair of
2850 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2851 * macros. So the thread running this has no valid thread state, as
2852 * far as Python is concerned. However, this calls some Python API
2853 * functions that cannot be called safely without a valid thread
2854 * state, in particular PyDict_GetItem.
2855 * As a temporary hack (although it may last for years ...), we
2856 * *rely* on not having a valid thread state in this function, in
2857 * order to create our own "from scratch".
2858 * This will deadlock if _PyPclose is ever called by a thread
2859 * holding the global lock.
2860 * (The OS/2 EMX thread support appears to cover the case where the
2861 * lock is already held - AIM Apr01)
2862 */
2863
2864static int _PyPclose(FILE *file)
2865{
2866 int result;
2867 int exit_code;
2868 int pipe_pid;
2869 PyObject *procObj, *pidObj, *intObj, *fileObj;
2870 int file_count;
2871#ifdef WITH_THREAD
2872 PyInterpreterState* pInterpreterState;
2873 PyThreadState* pThreadState;
2874#endif
2875
2876 /* Close the file handle first, to ensure it can't block the
2877 * child from exiting if it's the last handle.
2878 */
2879 result = fclose(file);
2880
2881#ifdef WITH_THREAD
2882 /* Bootstrap a valid thread state into existence. */
2883 pInterpreterState = PyInterpreterState_New();
2884 if (!pInterpreterState) {
2885 /* Well, we're hosed now! We don't have a thread
2886 * state, so can't call a nice error routine, or raise
2887 * an exception. Just die.
2888 */
2889 Py_FatalError("unable to allocate interpreter state "
2890 "when closing popen object.");
2891 return -1; /* unreachable */
2892 }
2893 pThreadState = PyThreadState_New(pInterpreterState);
2894 if (!pThreadState) {
2895 Py_FatalError("unable to allocate thread state "
2896 "when closing popen object.");
2897 return -1; /* unreachable */
2898 }
2899 /* Grab the global lock. Note that this will deadlock if the
2900 * current thread already has the lock! (see RED_FLAG comments
2901 * before this function)
2902 */
2903 PyEval_RestoreThread(pThreadState);
2904#endif
2905
2906 if (_PyPopenProcs)
2907 {
2908 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2909 (procObj = PyDict_GetItem(_PyPopenProcs,
2910 fileObj)) != NULL &&
2911 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2912 (intObj = PyList_GetItem(procObj,1)) != NULL)
2913 {
2914 pipe_pid = (int) PyInt_AsLong(pidObj);
2915 file_count = (int) PyInt_AsLong(intObj);
2916
2917 if (file_count > 1)
2918 {
2919 /* Still other files referencing process */
2920 file_count--;
2921 PyList_SetItem(procObj,1,
2922 PyInt_FromLong((long) file_count));
2923 }
2924 else
2925 {
2926 /* Last file for this process */
2927 if (result != EOF &&
2928 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2929 {
2930 /* extract exit status */
2931 if (WIFEXITED(exit_code))
2932 {
2933 result = WEXITSTATUS(exit_code);
2934 }
2935 else
2936 {
2937 errno = EPIPE;
2938 result = -1;
2939 }
2940 }
2941 else
2942 {
2943 /* Indicate failure - this will cause the file object
2944 * to raise an I/O error and translate the last
2945 * error code from errno. We do have a problem with
2946 * last errors that overlap the normal errno table,
2947 * but that's a consistent problem with the file object.
2948 */
2949 result = -1;
2950 }
2951 }
2952
2953 /* Remove this file pointer from dictionary */
2954 PyDict_DelItem(_PyPopenProcs, fileObj);
2955
2956 if (PyDict_Size(_PyPopenProcs) == 0)
2957 {
2958 Py_DECREF(_PyPopenProcs);
2959 _PyPopenProcs = NULL;
2960 }
2961
2962 } /* if object retrieval ok */
2963
2964 Py_XDECREF(fileObj);
2965 } /* if _PyPopenProcs */
2966
2967#ifdef WITH_THREAD
2968 /* Tear down the thread & interpreter states.
2969 * Note that interpreter state clear & delete functions automatically
2970 * call the thread clear & delete functions, and indeed insist on
2971 * doing that themselves. The lock must be held during the clear, but
2972 * need not be held during the delete.
2973 */
2974 PyInterpreterState_Clear(pInterpreterState);
2975 PyEval_ReleaseThread(pThreadState);
2976 PyInterpreterState_Delete(pInterpreterState);
2977#endif
2978
2979 return result;
2980}
2981
2982#endif /* PYCC_??? */
2983
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002984#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002985
2986/*
2987 * Portable 'popen' replacement for Win32.
2988 *
2989 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2990 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002991 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002992 */
2993
2994#include <malloc.h>
2995#include <io.h>
2996#include <fcntl.h>
2997
2998/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2999#define POPEN_1 1
3000#define POPEN_2 2
3001#define POPEN_3 3
3002#define POPEN_4 4
3003
3004static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003005static int _PyPclose(FILE *file);
3006
3007/*
3008 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003009 * for use when retrieving the process exit code. See _PyPclose() below
3010 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003011 */
3012static PyObject *_PyPopenProcs = NULL;
3013
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003014
3015/* popen that works from a GUI.
3016 *
3017 * The result of this function is a pipe (file) connected to the
3018 * processes stdin or stdout, depending on the requested mode.
3019 */
3020
3021static PyObject *
3022posix_popen(PyObject *self, PyObject *args)
3023{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003024 PyObject *f, *s;
3025 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003026
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003027 char *cmdstring;
3028 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003029 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003030 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003031 return NULL;
3032
3033 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003034
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003035 if (*mode == 'r')
3036 tm = _O_RDONLY;
3037 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003038 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003039 return NULL;
3040 } else
3041 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003042
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003043 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003044 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003045 return NULL;
3046 }
3047
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003048 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003049 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003050 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003051 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003052 else
3053 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3054
3055 return f;
3056}
3057
3058/* Variation on win32pipe.popen
3059 *
3060 * The result of this function is a pipe (file) connected to the
3061 * process's stdin, and a pipe connected to the process's stdout.
3062 */
3063
3064static PyObject *
3065win32_popen2(PyObject *self, PyObject *args)
3066{
3067 PyObject *f;
3068 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003069
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003070 char *cmdstring;
3071 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003072 int bufsize = -1;
3073 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003074 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003075
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003076 if (*mode == 't')
3077 tm = _O_TEXT;
3078 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003079 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003080 return NULL;
3081 } else
3082 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003083
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003084 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003085 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003086 return NULL;
3087 }
3088
3089 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003090
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003091 return f;
3092}
3093
3094/*
3095 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003096 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003097 * The result of this function is 3 pipes - the process's stdin,
3098 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003099 */
3100
3101static PyObject *
3102win32_popen3(PyObject *self, PyObject *args)
3103{
3104 PyObject *f;
3105 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003106
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003107 char *cmdstring;
3108 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003109 int bufsize = -1;
3110 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003111 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003112
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003113 if (*mode == 't')
3114 tm = _O_TEXT;
3115 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003116 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003117 return NULL;
3118 } else
3119 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003120
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003121 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003122 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003123 return NULL;
3124 }
3125
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003126 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003127
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003128 return f;
3129}
3130
3131/*
3132 * Variation on win32pipe.popen
3133 *
Tim Peters5aa91602002-01-30 05:46:57 +00003134 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003135 * and stdout+stderr combined as a single pipe.
3136 */
3137
3138static PyObject *
3139win32_popen4(PyObject *self, PyObject *args)
3140{
3141 PyObject *f;
3142 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003143
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003144 char *cmdstring;
3145 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003146 int bufsize = -1;
3147 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003148 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003149
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003150 if (*mode == 't')
3151 tm = _O_TEXT;
3152 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003153 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003154 return NULL;
3155 } else
3156 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003157
3158 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003159 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003160 return NULL;
3161 }
3162
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003163 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003164
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003165 return f;
3166}
3167
Mark Hammond08501372001-01-31 07:30:29 +00003168static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003169_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003170 HANDLE hStdin,
3171 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003172 HANDLE hStderr,
3173 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003174{
3175 PROCESS_INFORMATION piProcInfo;
3176 STARTUPINFO siStartInfo;
3177 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003178 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003179 int i;
3180 int x;
3181
3182 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003183 char *comshell;
3184
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003185 s1 = (char *)_alloca(i);
3186 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3187 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003188
3189 /* Explicitly check if we are using COMMAND.COM. If we are
3190 * then use the w9xpopen hack.
3191 */
3192 comshell = s1 + x;
3193 while (comshell >= s1 && *comshell != '\\')
3194 --comshell;
3195 ++comshell;
3196
3197 if (GetVersion() < 0x80000000 &&
3198 _stricmp(comshell, "command.com") != 0) {
3199 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003200 x = i + strlen(s3) + strlen(cmdstring) + 1;
3201 s2 = (char *)_alloca(x);
3202 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003203 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003204 }
3205 else {
3206 /*
Tim Peters402d5982001-08-27 06:37:48 +00003207 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3208 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003209 */
Mark Hammond08501372001-01-31 07:30:29 +00003210 char modulepath[_MAX_PATH];
3211 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003212 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3213 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003214 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003215 x = i+1;
3216 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003217 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003218 strncat(modulepath,
3219 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003220 (sizeof(modulepath)/sizeof(modulepath[0]))
3221 -strlen(modulepath));
3222 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003223 /* Eeek - file-not-found - possibly an embedding
3224 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003225 */
Tim Peters5aa91602002-01-30 05:46:57 +00003226 strncpy(modulepath,
3227 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003228 sizeof(modulepath)/sizeof(modulepath[0]));
3229 if (modulepath[strlen(modulepath)-1] != '\\')
3230 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003231 strncat(modulepath,
3232 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003233 (sizeof(modulepath)/sizeof(modulepath[0]))
3234 -strlen(modulepath));
3235 /* No where else to look - raise an easily identifiable
3236 error, rather than leaving Windows to report
3237 "file not found" - as the user is probably blissfully
3238 unaware this shim EXE is used, and it will confuse them.
3239 (well, it confused me for a while ;-)
3240 */
3241 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003242 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003243 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003244 "for popen to work with your shell "
3245 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003246 szConsoleSpawn);
3247 return FALSE;
3248 }
3249 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003250 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003251 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003252 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003253
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003254 s2 = (char *)_alloca(x);
3255 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003256 /* To maintain correct argument passing semantics,
3257 we pass the command-line as it stands, and allow
3258 quoting to be applied. w9xpopen.exe will then
3259 use its argv vector, and re-quote the necessary
3260 args for the ultimate child process.
3261 */
Tim Peters75cdad52001-11-28 22:07:30 +00003262 PyOS_snprintf(
3263 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003264 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003265 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003266 s1,
3267 s3,
3268 cmdstring);
3269 }
3270 }
3271
3272 /* Could be an else here to try cmd.exe / command.com in the path
3273 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003274 else {
Tim Peters402d5982001-08-27 06:37:48 +00003275 PyErr_SetString(PyExc_RuntimeError,
3276 "Cannot locate a COMSPEC environment variable to "
3277 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003278 return FALSE;
3279 }
Tim Peters5aa91602002-01-30 05:46:57 +00003280
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003281 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3282 siStartInfo.cb = sizeof(STARTUPINFO);
3283 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3284 siStartInfo.hStdInput = hStdin;
3285 siStartInfo.hStdOutput = hStdout;
3286 siStartInfo.hStdError = hStderr;
3287 siStartInfo.wShowWindow = SW_HIDE;
3288
3289 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003290 s2,
3291 NULL,
3292 NULL,
3293 TRUE,
Mark Hammond155adbd2002-07-14 23:28:16 +00003294 0, /* no new console so Ctrl+C kills child too */
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003295 NULL,
3296 NULL,
3297 &siStartInfo,
3298 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003299 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003300 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003301
Mark Hammondb37a3732000-08-14 04:47:33 +00003302 /* Return process handle */
3303 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003304 return TRUE;
3305 }
Tim Peters402d5982001-08-27 06:37:48 +00003306 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003307 return FALSE;
3308}
3309
3310/* The following code is based off of KB: Q190351 */
3311
3312static PyObject *
3313_PyPopen(char *cmdstring, int mode, int n)
3314{
3315 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3316 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003317 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003318
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003319 SECURITY_ATTRIBUTES saAttr;
3320 BOOL fSuccess;
3321 int fd1, fd2, fd3;
3322 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003323 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003324 PyObject *f;
3325
3326 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3327 saAttr.bInheritHandle = TRUE;
3328 saAttr.lpSecurityDescriptor = NULL;
3329
3330 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3331 return win32_error("CreatePipe", NULL);
3332
3333 /* Create new output read handle and the input write handle. Set
3334 * the inheritance properties to FALSE. Otherwise, the child inherits
3335 * the these handles; resulting in non-closeable handles to the pipes
3336 * being created. */
3337 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003338 GetCurrentProcess(), &hChildStdinWrDup, 0,
3339 FALSE,
3340 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003341 if (!fSuccess)
3342 return win32_error("DuplicateHandle", NULL);
3343
3344 /* Close the inheritable version of ChildStdin
3345 that we're using. */
3346 CloseHandle(hChildStdinWr);
3347
3348 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3349 return win32_error("CreatePipe", NULL);
3350
3351 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003352 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3353 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003354 if (!fSuccess)
3355 return win32_error("DuplicateHandle", NULL);
3356
3357 /* Close the inheritable version of ChildStdout
3358 that we're using. */
3359 CloseHandle(hChildStdoutRd);
3360
3361 if (n != POPEN_4) {
3362 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3363 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003364 fSuccess = DuplicateHandle(GetCurrentProcess(),
3365 hChildStderrRd,
3366 GetCurrentProcess(),
3367 &hChildStderrRdDup, 0,
3368 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003369 if (!fSuccess)
3370 return win32_error("DuplicateHandle", NULL);
3371 /* Close the inheritable version of ChildStdErr that we're using. */
3372 CloseHandle(hChildStderrRd);
3373 }
Tim Peters5aa91602002-01-30 05:46:57 +00003374
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003375 switch (n) {
3376 case POPEN_1:
3377 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3378 case _O_WRONLY | _O_TEXT:
3379 /* Case for writing to child Stdin in text mode. */
3380 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3381 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003382 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003383 PyFile_SetBufSize(f, 0);
3384 /* We don't care about these pipes anymore, so close them. */
3385 CloseHandle(hChildStdoutRdDup);
3386 CloseHandle(hChildStderrRdDup);
3387 break;
3388
3389 case _O_RDONLY | _O_TEXT:
3390 /* Case for reading from child Stdout in text mode. */
3391 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3392 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003393 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003394 PyFile_SetBufSize(f, 0);
3395 /* We don't care about these pipes anymore, so close them. */
3396 CloseHandle(hChildStdinWrDup);
3397 CloseHandle(hChildStderrRdDup);
3398 break;
3399
3400 case _O_RDONLY | _O_BINARY:
3401 /* Case for readinig from child Stdout in binary mode. */
3402 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3403 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003404 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003405 PyFile_SetBufSize(f, 0);
3406 /* We don't care about these pipes anymore, so close them. */
3407 CloseHandle(hChildStdinWrDup);
3408 CloseHandle(hChildStderrRdDup);
3409 break;
3410
3411 case _O_WRONLY | _O_BINARY:
3412 /* Case for writing to child Stdin in binary mode. */
3413 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3414 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003415 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003416 PyFile_SetBufSize(f, 0);
3417 /* We don't care about these pipes anymore, so close them. */
3418 CloseHandle(hChildStdoutRdDup);
3419 CloseHandle(hChildStderrRdDup);
3420 break;
3421 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003422 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003423 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003424
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003425 case POPEN_2:
3426 case POPEN_4:
3427 {
3428 char *m1, *m2;
3429 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003430
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003431 if (mode && _O_TEXT) {
3432 m1 = "r";
3433 m2 = "w";
3434 } else {
3435 m1 = "rb";
3436 m2 = "wb";
3437 }
3438
3439 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3440 f1 = _fdopen(fd1, m2);
3441 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3442 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003443 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003444 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003445 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003446 PyFile_SetBufSize(p2, 0);
3447
3448 if (n != 4)
3449 CloseHandle(hChildStderrRdDup);
3450
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003451 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003452 Py_XDECREF(p1);
3453 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003454 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003455 break;
3456 }
Tim Peters5aa91602002-01-30 05:46:57 +00003457
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003458 case POPEN_3:
3459 {
3460 char *m1, *m2;
3461 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003462
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003463 if (mode && _O_TEXT) {
3464 m1 = "r";
3465 m2 = "w";
3466 } else {
3467 m1 = "rb";
3468 m2 = "wb";
3469 }
3470
3471 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3472 f1 = _fdopen(fd1, m2);
3473 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3474 f2 = _fdopen(fd2, m1);
3475 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3476 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003477 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003478 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3479 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003480 PyFile_SetBufSize(p1, 0);
3481 PyFile_SetBufSize(p2, 0);
3482 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003483 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003484 Py_XDECREF(p1);
3485 Py_XDECREF(p2);
3486 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003487 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003488 break;
3489 }
3490 }
3491
3492 if (n == POPEN_4) {
3493 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003494 hChildStdinRd,
3495 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003496 hChildStdoutWr,
3497 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003498 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003499 }
3500 else {
3501 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003502 hChildStdinRd,
3503 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003504 hChildStderrWr,
3505 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003506 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003507 }
3508
Mark Hammondb37a3732000-08-14 04:47:33 +00003509 /*
3510 * Insert the files we've created into the process dictionary
3511 * all referencing the list with the process handle and the
3512 * initial number of files (see description below in _PyPclose).
3513 * Since if _PyPclose later tried to wait on a process when all
3514 * handles weren't closed, it could create a deadlock with the
3515 * child, we spend some energy here to try to ensure that we
3516 * either insert all file handles into the dictionary or none
3517 * at all. It's a little clumsy with the various popen modes
3518 * and variable number of files involved.
3519 */
3520 if (!_PyPopenProcs) {
3521 _PyPopenProcs = PyDict_New();
3522 }
3523
3524 if (_PyPopenProcs) {
3525 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3526 int ins_rc[3];
3527
3528 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3529 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3530
3531 procObj = PyList_New(2);
3532 hProcessObj = PyLong_FromVoidPtr(hProcess);
3533 intObj = PyInt_FromLong(file_count);
3534
3535 if (procObj && hProcessObj && intObj) {
3536 PyList_SetItem(procObj,0,hProcessObj);
3537 PyList_SetItem(procObj,1,intObj);
3538
3539 fileObj[0] = PyLong_FromVoidPtr(f1);
3540 if (fileObj[0]) {
3541 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3542 fileObj[0],
3543 procObj);
3544 }
3545 if (file_count >= 2) {
3546 fileObj[1] = PyLong_FromVoidPtr(f2);
3547 if (fileObj[1]) {
3548 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3549 fileObj[1],
3550 procObj);
3551 }
3552 }
3553 if (file_count >= 3) {
3554 fileObj[2] = PyLong_FromVoidPtr(f3);
3555 if (fileObj[2]) {
3556 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3557 fileObj[2],
3558 procObj);
3559 }
3560 }
3561
3562 if (ins_rc[0] < 0 || !fileObj[0] ||
3563 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3564 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3565 /* Something failed - remove any dictionary
3566 * entries that did make it.
3567 */
3568 if (!ins_rc[0] && fileObj[0]) {
3569 PyDict_DelItem(_PyPopenProcs,
3570 fileObj[0]);
3571 }
3572 if (!ins_rc[1] && fileObj[1]) {
3573 PyDict_DelItem(_PyPopenProcs,
3574 fileObj[1]);
3575 }
3576 if (!ins_rc[2] && fileObj[2]) {
3577 PyDict_DelItem(_PyPopenProcs,
3578 fileObj[2]);
3579 }
3580 }
3581 }
Tim Peters5aa91602002-01-30 05:46:57 +00003582
Mark Hammondb37a3732000-08-14 04:47:33 +00003583 /*
3584 * Clean up our localized references for the dictionary keys
3585 * and value since PyDict_SetItem will Py_INCREF any copies
3586 * that got placed in the dictionary.
3587 */
3588 Py_XDECREF(procObj);
3589 Py_XDECREF(fileObj[0]);
3590 Py_XDECREF(fileObj[1]);
3591 Py_XDECREF(fileObj[2]);
3592 }
3593
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003594 /* Child is launched. Close the parents copy of those pipe
3595 * handles that only the child should have open. You need to
3596 * make sure that no handles to the write end of the output pipe
3597 * are maintained in this process or else the pipe will not close
3598 * when the child process exits and the ReadFile will hang. */
3599
3600 if (!CloseHandle(hChildStdinRd))
3601 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003602
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003603 if (!CloseHandle(hChildStdoutWr))
3604 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003605
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003606 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3607 return win32_error("CloseHandle", NULL);
3608
3609 return f;
3610}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003611
3612/*
3613 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3614 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003615 *
3616 * This function uses the _PyPopenProcs dictionary in order to map the
3617 * input file pointer to information about the process that was
3618 * originally created by the popen* call that created the file pointer.
3619 * The dictionary uses the file pointer as a key (with one entry
3620 * inserted for each file returned by the original popen* call) and a
3621 * single list object as the value for all files from a single call.
3622 * The list object contains the Win32 process handle at [0], and a file
3623 * count at [1], which is initialized to the total number of file
3624 * handles using that list.
3625 *
3626 * This function closes whichever handle it is passed, and decrements
3627 * the file count in the dictionary for the process handle pointed to
3628 * by this file. On the last close (when the file count reaches zero),
3629 * this function will wait for the child process and then return its
3630 * exit code as the result of the close() operation. This permits the
3631 * files to be closed in any order - it is always the close() of the
3632 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003633 */
Tim Peters736aa322000-09-01 06:51:24 +00003634
3635 /* RED_FLAG 31-Aug-2000 Tim
3636 * This is always called (today!) between a pair of
3637 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3638 * macros. So the thread running this has no valid thread state, as
3639 * far as Python is concerned. However, this calls some Python API
3640 * functions that cannot be called safely without a valid thread
3641 * state, in particular PyDict_GetItem.
3642 * As a temporary hack (although it may last for years ...), we
3643 * *rely* on not having a valid thread state in this function, in
3644 * order to create our own "from scratch".
3645 * This will deadlock if _PyPclose is ever called by a thread
3646 * holding the global lock.
3647 */
3648
Fredrik Lundh56055a42000-07-23 19:47:12 +00003649static int _PyPclose(FILE *file)
3650{
Fredrik Lundh20318932000-07-26 17:29:12 +00003651 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003652 DWORD exit_code;
3653 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003654 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3655 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003656#ifdef WITH_THREAD
3657 PyInterpreterState* pInterpreterState;
3658 PyThreadState* pThreadState;
3659#endif
3660
Fredrik Lundh20318932000-07-26 17:29:12 +00003661 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003662 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003663 */
3664 result = fclose(file);
3665
Tim Peters736aa322000-09-01 06:51:24 +00003666#ifdef WITH_THREAD
3667 /* Bootstrap a valid thread state into existence. */
3668 pInterpreterState = PyInterpreterState_New();
3669 if (!pInterpreterState) {
3670 /* Well, we're hosed now! We don't have a thread
3671 * state, so can't call a nice error routine, or raise
3672 * an exception. Just die.
3673 */
3674 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003675 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003676 return -1; /* unreachable */
3677 }
3678 pThreadState = PyThreadState_New(pInterpreterState);
3679 if (!pThreadState) {
3680 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003681 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003682 return -1; /* unreachable */
3683 }
3684 /* Grab the global lock. Note that this will deadlock if the
3685 * current thread already has the lock! (see RED_FLAG comments
3686 * before this function)
3687 */
3688 PyEval_RestoreThread(pThreadState);
3689#endif
3690
Fredrik Lundh56055a42000-07-23 19:47:12 +00003691 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003692 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3693 (procObj = PyDict_GetItem(_PyPopenProcs,
3694 fileObj)) != NULL &&
3695 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3696 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3697
3698 hProcess = PyLong_AsVoidPtr(hProcessObj);
3699 file_count = PyInt_AsLong(intObj);
3700
3701 if (file_count > 1) {
3702 /* Still other files referencing process */
3703 file_count--;
3704 PyList_SetItem(procObj,1,
3705 PyInt_FromLong(file_count));
3706 } else {
3707 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003708 if (result != EOF &&
3709 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3710 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003711 /* Possible truncation here in 16-bit environments, but
3712 * real exit codes are just the lower byte in any event.
3713 */
3714 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003715 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003716 /* Indicate failure - this will cause the file object
3717 * to raise an I/O error and translate the last Win32
3718 * error code from errno. We do have a problem with
3719 * last errors that overlap the normal errno table,
3720 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003721 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003722 if (result != EOF) {
3723 /* If the error wasn't from the fclose(), then
3724 * set errno for the file object error handling.
3725 */
3726 errno = GetLastError();
3727 }
3728 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003729 }
3730
3731 /* Free up the native handle at this point */
3732 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003733 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003734
Mark Hammondb37a3732000-08-14 04:47:33 +00003735 /* Remove this file pointer from dictionary */
3736 PyDict_DelItem(_PyPopenProcs, fileObj);
3737
3738 if (PyDict_Size(_PyPopenProcs) == 0) {
3739 Py_DECREF(_PyPopenProcs);
3740 _PyPopenProcs = NULL;
3741 }
3742
3743 } /* if object retrieval ok */
3744
3745 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003746 } /* if _PyPopenProcs */
3747
Tim Peters736aa322000-09-01 06:51:24 +00003748#ifdef WITH_THREAD
3749 /* Tear down the thread & interpreter states.
3750 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003751 * call the thread clear & delete functions, and indeed insist on
3752 * doing that themselves. The lock must be held during the clear, but
3753 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003754 */
3755 PyInterpreterState_Clear(pInterpreterState);
3756 PyEval_ReleaseThread(pThreadState);
3757 PyInterpreterState_Delete(pInterpreterState);
3758#endif
3759
Fredrik Lundh56055a42000-07-23 19:47:12 +00003760 return result;
3761}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003762
3763#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003765posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003766{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003767 char *name;
3768 char *mode = "r";
3769 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003770 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003771 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003772 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003773 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003774 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003775 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003776 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003777 if (fp == NULL)
3778 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003779 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003780 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003781 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003782 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003783}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003784
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003785#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003786#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003788
Guido van Rossumb6775db1994-08-01 11:34:53 +00003789#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003790PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003791"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003792Set the current process's user id.");
3793
Barry Warsaw53699e91996-12-10 23:23:01 +00003794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003795posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003796{
3797 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003798 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003799 return NULL;
3800 if (setuid(uid) < 0)
3801 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003802 Py_INCREF(Py_None);
3803 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003804}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003805#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003806
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003807
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003808#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003809PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003810"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003811Set the current process's effective user id.");
3812
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003813static PyObject *
3814posix_seteuid (PyObject *self, PyObject *args)
3815{
3816 int euid;
3817 if (!PyArg_ParseTuple(args, "i", &euid)) {
3818 return NULL;
3819 } else if (seteuid(euid) < 0) {
3820 return posix_error();
3821 } else {
3822 Py_INCREF(Py_None);
3823 return Py_None;
3824 }
3825}
3826#endif /* HAVE_SETEUID */
3827
3828#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003829PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003830"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003831Set the current process's effective group id.");
3832
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003833static PyObject *
3834posix_setegid (PyObject *self, PyObject *args)
3835{
3836 int egid;
3837 if (!PyArg_ParseTuple(args, "i", &egid)) {
3838 return NULL;
3839 } else if (setegid(egid) < 0) {
3840 return posix_error();
3841 } else {
3842 Py_INCREF(Py_None);
3843 return Py_None;
3844 }
3845}
3846#endif /* HAVE_SETEGID */
3847
3848#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003849PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003850"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003851Set the current process's real and effective user ids.");
3852
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003853static PyObject *
3854posix_setreuid (PyObject *self, PyObject *args)
3855{
3856 int ruid, euid;
3857 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3858 return NULL;
3859 } else if (setreuid(ruid, euid) < 0) {
3860 return posix_error();
3861 } else {
3862 Py_INCREF(Py_None);
3863 return Py_None;
3864 }
3865}
3866#endif /* HAVE_SETREUID */
3867
3868#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003869PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003870"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003871Set the current process's real and effective group ids.");
3872
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003873static PyObject *
3874posix_setregid (PyObject *self, PyObject *args)
3875{
3876 int rgid, egid;
3877 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3878 return NULL;
3879 } else if (setregid(rgid, egid) < 0) {
3880 return posix_error();
3881 } else {
3882 Py_INCREF(Py_None);
3883 return Py_None;
3884 }
3885}
3886#endif /* HAVE_SETREGID */
3887
Guido van Rossumb6775db1994-08-01 11:34:53 +00003888#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003889PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003890"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003891Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003892
Barry Warsaw53699e91996-12-10 23:23:01 +00003893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003894posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003895{
3896 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003897 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003898 return NULL;
3899 if (setgid(gid) < 0)
3900 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003901 Py_INCREF(Py_None);
3902 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003903}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003904#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003905
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003906#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003907PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003908"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003909Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003910
3911static PyObject *
3912posix_setgroups(PyObject *self, PyObject *args)
3913{
3914 PyObject *groups;
3915 int i, len;
3916 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003917
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003918 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3919 return NULL;
3920 if (!PySequence_Check(groups)) {
3921 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3922 return NULL;
3923 }
3924 len = PySequence_Size(groups);
3925 if (len > MAX_GROUPS) {
3926 PyErr_SetString(PyExc_ValueError, "too many groups");
3927 return NULL;
3928 }
3929 for(i = 0; i < len; i++) {
3930 PyObject *elem;
3931 elem = PySequence_GetItem(groups, i);
3932 if (!elem)
3933 return NULL;
3934 if (!PyInt_Check(elem)) {
3935 PyErr_SetString(PyExc_TypeError,
3936 "groups must be integers");
3937 Py_DECREF(elem);
3938 return NULL;
3939 }
3940 /* XXX: check that value fits into gid_t. */
3941 grouplist[i] = PyInt_AsLong(elem);
3942 Py_DECREF(elem);
3943 }
3944
3945 if (setgroups(len, grouplist) < 0)
3946 return posix_error();
3947 Py_INCREF(Py_None);
3948 return Py_None;
3949}
3950#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003951
Guido van Rossumb6775db1994-08-01 11:34:53 +00003952#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003953PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003954"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003955Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003956
Barry Warsaw53699e91996-12-10 23:23:01 +00003957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003958posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003959{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003960 int pid, options;
3961#ifdef UNION_WAIT
3962 union wait status;
3963#define status_i (status.w_status)
3964#else
3965 int status;
3966#define status_i status
3967#endif
3968 status_i = 0;
3969
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003970 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003971 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003972 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003973 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00003974 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003975 if (pid == -1)
3976 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003977 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003978 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003979}
3980
Tim Petersab034fa2002-02-01 11:27:43 +00003981#elif defined(HAVE_CWAIT)
3982
3983/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003984PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003985"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003986"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00003987
3988static PyObject *
3989posix_waitpid(PyObject *self, PyObject *args)
3990{
3991 int pid, options;
3992 int status;
3993
3994 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
3995 return NULL;
3996 Py_BEGIN_ALLOW_THREADS
3997 pid = _cwait(&status, pid, options);
3998 Py_END_ALLOW_THREADS
3999 if (pid == -1)
4000 return posix_error();
4001 else
4002 /* shift the status left a byte so this is more like the
4003 POSIX waitpid */
4004 return Py_BuildValue("ii", pid, status << 8);
4005}
4006#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004007
Guido van Rossumad0ee831995-03-01 10:34:45 +00004008#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004010"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004011Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004012
Barry Warsaw53699e91996-12-10 23:23:01 +00004013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004014posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004015{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004016 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004017#ifdef UNION_WAIT
4018 union wait status;
4019#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004020#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004021 int status;
4022#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004023#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004024 if (!PyArg_ParseTuple(args, ":wait"))
4025 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004026 status_i = 0;
4027 Py_BEGIN_ALLOW_THREADS
4028 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004029 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004030 if (pid == -1)
4031 return posix_error();
4032 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004033 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004034#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004035}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004036#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004037
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004038
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004039PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004040"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004041Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004042
Barry Warsaw53699e91996-12-10 23:23:01 +00004043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004044posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004045{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004046#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004047 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004048#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004049 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004050#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004051}
4052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004053
Guido van Rossumb6775db1994-08-01 11:34:53 +00004054#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004055PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004056"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004057Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004058
Barry Warsaw53699e91996-12-10 23:23:01 +00004059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004060posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004061{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004062 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004063 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004064 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004065 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004066 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004067 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004068 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004069 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004070 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004071 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004072 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004073}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004074#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004076
Guido van Rossumb6775db1994-08-01 11:34:53 +00004077#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004078PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004079"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004080Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004081
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004083posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004084{
Mark Hammondef8b6542001-05-13 08:04:26 +00004085 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004086}
4087#endif /* HAVE_SYMLINK */
4088
4089
4090#ifdef HAVE_TIMES
4091#ifndef HZ
4092#define HZ 60 /* Universal constant :-) */
4093#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004094
Guido van Rossumd48f2521997-12-05 22:19:34 +00004095#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4096static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004097system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004098{
4099 ULONG value = 0;
4100
4101 Py_BEGIN_ALLOW_THREADS
4102 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4103 Py_END_ALLOW_THREADS
4104
4105 return value;
4106}
4107
4108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004109posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004110{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004111 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004112 return NULL;
4113
4114 /* Currently Only Uptime is Provided -- Others Later */
4115 return Py_BuildValue("ddddd",
4116 (double)0 /* t.tms_utime / HZ */,
4117 (double)0 /* t.tms_stime / HZ */,
4118 (double)0 /* t.tms_cutime / HZ */,
4119 (double)0 /* t.tms_cstime / HZ */,
4120 (double)system_uptime() / 1000);
4121}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004122#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004123static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004124posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004125{
4126 struct tms t;
4127 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004128 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004129 return NULL;
4130 errno = 0;
4131 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004132 if (c == (clock_t) -1)
4133 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004134 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004135 (double)t.tms_utime / HZ,
4136 (double)t.tms_stime / HZ,
4137 (double)t.tms_cutime / HZ,
4138 (double)t.tms_cstime / HZ,
4139 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004140}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004141#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004142#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004143
4144
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004145#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004146#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004148posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004149{
4150 FILETIME create, exit, kernel, user;
4151 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004152 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004153 return NULL;
4154 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004155 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4156 /* The fields of a FILETIME structure are the hi and lo part
4157 of a 64-bit value expressed in 100 nanosecond units.
4158 1e7 is one second in such units; 1e-7 the inverse.
4159 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4160 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004161 return Py_BuildValue(
4162 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004163 (double)(kernel.dwHighDateTime*429.4967296 +
4164 kernel.dwLowDateTime*1e-7),
4165 (double)(user.dwHighDateTime*429.4967296 +
4166 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004167 (double)0,
4168 (double)0,
4169 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004170}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004171#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004172
4173#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004174PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004175"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004176Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004177#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004179
Guido van Rossumb6775db1994-08-01 11:34:53 +00004180#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004181PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004182"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004183Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004184
Barry Warsaw53699e91996-12-10 23:23:01 +00004185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004186posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004187{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004188 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004189 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004190 if (setsid() < 0)
4191 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004192 Py_INCREF(Py_None);
4193 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004194}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004195#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004196
Guido van Rossumb6775db1994-08-01 11:34:53 +00004197#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004198PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004199"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004200Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004201
Barry Warsaw53699e91996-12-10 23:23:01 +00004202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004203posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004204{
4205 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004206 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004207 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004208 if (setpgid(pid, pgrp) < 0)
4209 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004210 Py_INCREF(Py_None);
4211 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004212}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004213#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004214
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004215
Guido van Rossumb6775db1994-08-01 11:34:53 +00004216#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004217PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004218"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004219Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004220
Barry Warsaw53699e91996-12-10 23:23:01 +00004221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004222posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004223{
4224 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004225 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004226 return NULL;
4227 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004228 if (pgid < 0)
4229 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004230 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004231}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004232#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004234
Guido van Rossumb6775db1994-08-01 11:34:53 +00004235#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004236PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004237"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004238Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004239
Barry Warsaw53699e91996-12-10 23:23:01 +00004240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004241posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004242{
4243 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004244 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004245 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004246 if (tcsetpgrp(fd, pgid) < 0)
4247 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004248 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004249 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004250}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004251#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004252
Guido van Rossum687dd131993-05-17 08:34:16 +00004253/* Functions acting on file descriptors */
4254
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004255PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004256"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004257Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004258
Barry Warsaw53699e91996-12-10 23:23:01 +00004259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004260posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004261{
Mark Hammondef8b6542001-05-13 08:04:26 +00004262 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004263 int flag;
4264 int mode = 0777;
4265 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004266 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004267 Py_FileSystemDefaultEncoding, &file,
4268 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004269 return NULL;
4270
Barry Warsaw53699e91996-12-10 23:23:01 +00004271 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004272 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004273 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004274 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004275 return posix_error_with_allocated_filename(file);
4276 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004277 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004278}
4279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004280
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004281PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004282"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004283Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004284
Barry Warsaw53699e91996-12-10 23:23:01 +00004285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004286posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004287{
4288 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004289 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004290 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004291 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004292 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004293 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004294 if (res < 0)
4295 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004296 Py_INCREF(Py_None);
4297 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004298}
4299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004300
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004301PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004302"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004303Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004304
Barry Warsaw53699e91996-12-10 23:23:01 +00004305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004306posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004307{
4308 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004309 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004310 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004311 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004312 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004313 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004314 if (fd < 0)
4315 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004316 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004317}
4318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004319
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004320PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004321"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004322Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004323
Barry Warsaw53699e91996-12-10 23:23:01 +00004324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004325posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004326{
4327 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004328 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004329 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004330 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004331 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004332 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004333 if (res < 0)
4334 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004335 Py_INCREF(Py_None);
4336 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004337}
4338
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004339
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004340PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004341"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004342Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004343
Barry Warsaw53699e91996-12-10 23:23:01 +00004344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004345posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004346{
4347 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004348#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004349 LONG_LONG pos, res;
4350#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004351 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004352#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004353 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004354 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004355 return NULL;
4356#ifdef SEEK_SET
4357 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4358 switch (how) {
4359 case 0: how = SEEK_SET; break;
4360 case 1: how = SEEK_CUR; break;
4361 case 2: how = SEEK_END; break;
4362 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004363#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004364
4365#if !defined(HAVE_LARGEFILE_SUPPORT)
4366 pos = PyInt_AsLong(posobj);
4367#else
4368 pos = PyLong_Check(posobj) ?
4369 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4370#endif
4371 if (PyErr_Occurred())
4372 return NULL;
4373
Barry Warsaw53699e91996-12-10 23:23:01 +00004374 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004375#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004376 res = _lseeki64(fd, pos, how);
4377#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004378 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004379#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004380 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004381 if (res < 0)
4382 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004383
4384#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004385 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004386#else
4387 return PyLong_FromLongLong(res);
4388#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004389}
4390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004391
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004392PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004393"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004394Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004395
Barry Warsaw53699e91996-12-10 23:23:01 +00004396static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004397posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004398{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004399 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004400 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004401 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004402 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004403 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004404 if (buffer == NULL)
4405 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004406 Py_BEGIN_ALLOW_THREADS
4407 n = read(fd, PyString_AsString(buffer), size);
4408 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004409 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004410 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004411 return posix_error();
4412 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004413 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004414 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004415 return buffer;
4416}
4417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004418
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004419PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004420"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004421Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004422
Barry Warsaw53699e91996-12-10 23:23:01 +00004423static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004424posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004425{
4426 int fd, size;
4427 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004428 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004429 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004430 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004431 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004432 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004433 if (size < 0)
4434 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004435 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004436}
4437
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004438
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004439PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004440"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004441Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004442
Barry Warsaw53699e91996-12-10 23:23:01 +00004443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004444posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004445{
4446 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004447 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004448 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004449 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004450 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004451 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004452 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004453 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004454 if (res != 0)
4455 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004456
Fred Drake699f3522000-06-29 21:12:41 +00004457 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004458}
4459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004460
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004461PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004462"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004463Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004464
Barry Warsaw53699e91996-12-10 23:23:01 +00004465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004466posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004467{
Guido van Rossum687dd131993-05-17 08:34:16 +00004468 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004469 char *mode = "r";
4470 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004471 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004472 PyObject *f;
4473 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004474 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004475
Barry Warsaw53699e91996-12-10 23:23:01 +00004476 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004477 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004478 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004479 if (fp == NULL)
4480 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004481 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004482 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004483 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004484 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004485}
4486
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004487PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004488"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004489Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004490connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004491
4492static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004493posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004494{
4495 int fd;
4496 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4497 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004498 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004499}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004500
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004501#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004502PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004503"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004504Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004505
Barry Warsaw53699e91996-12-10 23:23:01 +00004506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004507posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004508{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004509#if defined(PYOS_OS2)
4510 HFILE read, write;
4511 APIRET rc;
4512
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004513 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004514 return NULL;
4515
4516 Py_BEGIN_ALLOW_THREADS
4517 rc = DosCreatePipe( &read, &write, 4096);
4518 Py_END_ALLOW_THREADS
4519 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004520 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004521
4522 return Py_BuildValue("(ii)", read, write);
4523#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004524#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004525 int fds[2];
4526 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004527 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004528 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004529 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004530 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004531 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004532 if (res != 0)
4533 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004534 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004535#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004536 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004537 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004538 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004539 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004540 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004541 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004542 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004543 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004544 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004545 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004546 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4547 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004548 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004549#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004550#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004551}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004552#endif /* HAVE_PIPE */
4553
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004554
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004555#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004556PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004557"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004558Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004559
Barry Warsaw53699e91996-12-10 23:23:01 +00004560static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004561posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004562{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004563 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004564 int mode = 0666;
4565 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004566 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004567 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004568 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004569 res = mkfifo(filename, mode);
4570 Py_END_ALLOW_THREADS
4571 if (res < 0)
4572 return posix_error();
4573 Py_INCREF(Py_None);
4574 return Py_None;
4575}
4576#endif
4577
4578
4579#ifdef HAVE_MKNOD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004580PyDoc_STRVAR(posix_mknod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004581"mknod(filename, [, mode=0600, major, minor])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004582Create a filesystem node (file, device special file or named pipe)\n\
4583named filename. mode specifies both the permissions to use and the\n\
4584type of node to be created, being combined (bitwise OR) with one of\n\
4585S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4586major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004587they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004588
4589
4590static PyObject *
4591posix_mknod(PyObject *self, PyObject *args)
4592{
4593 char *filename;
4594 int mode = 0600;
4595 int major = 0;
4596 int minor = 0;
4597 int res;
4598 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4599 &mode, &major, &minor))
4600 return NULL;
4601 Py_BEGIN_ALLOW_THREADS
4602 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004603 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004604 if (res < 0)
4605 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004606 Py_INCREF(Py_None);
4607 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004608}
4609#endif
4610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004611
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004612#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004613PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004614"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004615Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004616
Barry Warsaw53699e91996-12-10 23:23:01 +00004617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004618posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004619{
4620 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004621 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004622 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004623 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004624
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004625 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004626 return NULL;
4627
4628#if !defined(HAVE_LARGEFILE_SUPPORT)
4629 length = PyInt_AsLong(lenobj);
4630#else
4631 length = PyLong_Check(lenobj) ?
4632 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4633#endif
4634 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004635 return NULL;
4636
Barry Warsaw53699e91996-12-10 23:23:01 +00004637 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004638 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004639 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004640 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004641 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004642 return NULL;
4643 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004644 Py_INCREF(Py_None);
4645 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004646}
4647#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004648
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004649#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004650PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004651"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004652Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004653
Fred Drake762e2061999-08-26 17:23:54 +00004654/* Save putenv() parameters as values here, so we can collect them when they
4655 * get re-set with another call for the same key. */
4656static PyObject *posix_putenv_garbage;
4657
Tim Peters5aa91602002-01-30 05:46:57 +00004658static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004659posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004660{
4661 char *s1, *s2;
4662 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004663 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004664 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004665
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004666 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004667 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004668
4669#if defined(PYOS_OS2)
4670 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4671 APIRET rc;
4672
4673 if (strlen(s2) == 0) /* If New Value is an Empty String */
4674 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4675
4676 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4677 if (rc != NO_ERROR)
4678 return os2_error(rc);
4679
4680 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4681 APIRET rc;
4682
4683 if (strlen(s2) == 0) /* If New Value is an Empty String */
4684 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4685
4686 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4687 if (rc != NO_ERROR)
4688 return os2_error(rc);
4689 } else {
4690#endif
4691
Fred Drake762e2061999-08-26 17:23:54 +00004692 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004693 len = strlen(s1) + strlen(s2) + 2;
4694 /* len includes space for a trailing \0; the size arg to
4695 PyString_FromStringAndSize does not count that */
4696 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004697 if (newstr == NULL)
4698 return PyErr_NoMemory();
4699 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004700 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004701 if (putenv(new)) {
4702 posix_error();
4703 return NULL;
4704 }
Fred Drake762e2061999-08-26 17:23:54 +00004705 /* Install the first arg and newstr in posix_putenv_garbage;
4706 * this will cause previous value to be collected. This has to
4707 * happen after the real putenv() call because the old value
4708 * was still accessible until then. */
4709 if (PyDict_SetItem(posix_putenv_garbage,
4710 PyTuple_GET_ITEM(args, 0), newstr)) {
4711 /* really not much we can do; just leak */
4712 PyErr_Clear();
4713 }
4714 else {
4715 Py_DECREF(newstr);
4716 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004717
4718#if defined(PYOS_OS2)
4719 }
4720#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004721 Py_INCREF(Py_None);
4722 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004723}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004724#endif /* putenv */
4725
Guido van Rossumc524d952001-10-19 01:31:59 +00004726#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004727PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004728"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004729Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00004730
4731static PyObject *
4732posix_unsetenv(PyObject *self, PyObject *args)
4733{
4734 char *s1;
4735
4736 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4737 return NULL;
4738
4739 unsetenv(s1);
4740
4741 /* Remove the key from posix_putenv_garbage;
4742 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004743 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004744 * old value was still accessible until then.
4745 */
4746 if (PyDict_DelItem(posix_putenv_garbage,
4747 PyTuple_GET_ITEM(args, 0))) {
4748 /* really not much we can do; just leak */
4749 PyErr_Clear();
4750 }
4751
4752 Py_INCREF(Py_None);
4753 return Py_None;
4754}
4755#endif /* unsetenv */
4756
Guido van Rossumb6a47161997-09-15 22:54:34 +00004757#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004758PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004759"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004760Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004761
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004763posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004764{
4765 int code;
4766 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004767 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004768 return NULL;
4769 message = strerror(code);
4770 if (message == NULL) {
4771 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004772 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004773 return NULL;
4774 }
4775 return PyString_FromString(message);
4776}
4777#endif /* strerror */
4778
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004779
Guido van Rossumc9641791998-08-04 15:26:23 +00004780#ifdef HAVE_SYS_WAIT_H
4781
Fred Drake106c1a02002-04-23 15:58:02 +00004782#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004783PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004784"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004785Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00004786
4787static PyObject *
4788posix_WCOREDUMP(PyObject *self, PyObject *args)
4789{
4790#ifdef UNION_WAIT
4791 union wait status;
4792#define status_i (status.w_status)
4793#else
4794 int status;
4795#define status_i status
4796#endif
4797 status_i = 0;
4798
4799 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4800 {
4801 return NULL;
4802 }
4803
4804 return PyBool_FromLong(WCOREDUMP(status));
4805#undef status_i
4806}
4807#endif /* WCOREDUMP */
4808
4809#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004810PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004811"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004812Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004813job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00004814
4815static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004816posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004817{
4818#ifdef UNION_WAIT
4819 union wait status;
4820#define status_i (status.w_status)
4821#else
4822 int status;
4823#define status_i status
4824#endif
4825 status_i = 0;
4826
4827 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4828 {
4829 return NULL;
4830 }
4831
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004832 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004833#undef status_i
4834}
4835#endif /* WIFCONTINUED */
4836
Guido van Rossumc9641791998-08-04 15:26:23 +00004837#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004838PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004839"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004840Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004841
4842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004843posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004844{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004845#ifdef UNION_WAIT
4846 union wait status;
4847#define status_i (status.w_status)
4848#else
4849 int status;
4850#define status_i status
4851#endif
4852 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004853
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004854 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004855 {
4856 return NULL;
4857 }
Tim Peters5aa91602002-01-30 05:46:57 +00004858
Fred Drake106c1a02002-04-23 15:58:02 +00004859 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004860#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004861}
4862#endif /* WIFSTOPPED */
4863
4864#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004865PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004866"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004867Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004868
4869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004870posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004871{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004872#ifdef UNION_WAIT
4873 union wait status;
4874#define status_i (status.w_status)
4875#else
4876 int status;
4877#define status_i status
4878#endif
4879 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004880
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004881 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004882 {
4883 return NULL;
4884 }
Tim Peters5aa91602002-01-30 05:46:57 +00004885
Fred Drake106c1a02002-04-23 15:58:02 +00004886 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004887#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004888}
4889#endif /* WIFSIGNALED */
4890
4891#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004892PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004893"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004894Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004895system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004896
4897static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004898posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004899{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004900#ifdef UNION_WAIT
4901 union wait status;
4902#define status_i (status.w_status)
4903#else
4904 int status;
4905#define status_i status
4906#endif
4907 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004908
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004909 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004910 {
4911 return NULL;
4912 }
Tim Peters5aa91602002-01-30 05:46:57 +00004913
Fred Drake106c1a02002-04-23 15:58:02 +00004914 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004915#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004916}
4917#endif /* WIFEXITED */
4918
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004919#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004920PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004921"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004922Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004923
4924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004925posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004926{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004927#ifdef UNION_WAIT
4928 union wait status;
4929#define status_i (status.w_status)
4930#else
4931 int status;
4932#define status_i status
4933#endif
4934 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004935
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004936 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004937 {
4938 return NULL;
4939 }
Tim Peters5aa91602002-01-30 05:46:57 +00004940
Guido van Rossumc9641791998-08-04 15:26:23 +00004941 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004942#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004943}
4944#endif /* WEXITSTATUS */
4945
4946#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004947PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004948"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004949Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004950value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004951
4952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004953posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004954{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004955#ifdef UNION_WAIT
4956 union wait status;
4957#define status_i (status.w_status)
4958#else
4959 int status;
4960#define status_i status
4961#endif
4962 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004963
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004964 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004965 {
4966 return NULL;
4967 }
Tim Peters5aa91602002-01-30 05:46:57 +00004968
Guido van Rossumc9641791998-08-04 15:26:23 +00004969 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004970#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004971}
4972#endif /* WTERMSIG */
4973
4974#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004975PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004976"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004977Return the signal that stopped the process that provided\n\
4978the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004979
4980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004981posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004982{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004983#ifdef UNION_WAIT
4984 union wait status;
4985#define status_i (status.w_status)
4986#else
4987 int status;
4988#define status_i status
4989#endif
4990 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004991
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004992 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004993 {
4994 return NULL;
4995 }
Tim Peters5aa91602002-01-30 05:46:57 +00004996
Guido van Rossumc9641791998-08-04 15:26:23 +00004997 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004998#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004999}
5000#endif /* WSTOPSIG */
5001
5002#endif /* HAVE_SYS_WAIT_H */
5003
5004
Guido van Rossum94f6f721999-01-06 18:42:14 +00005005#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005006#ifdef _SCO_DS
5007/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5008 needed definitions in sys/statvfs.h */
5009#define _SVID3
5010#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005011#include <sys/statvfs.h>
5012
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005013static PyObject*
5014_pystatvfs_fromstructstatvfs(struct statvfs st) {
5015 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5016 if (v == NULL)
5017 return NULL;
5018
5019#if !defined(HAVE_LARGEFILE_SUPPORT)
5020 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5021 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5022 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5023 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5024 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5025 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5026 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5027 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5028 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5029 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5030#else
5031 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5032 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005033 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005034 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005035 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005036 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5037 PyStructSequence_SET_ITEM(v, 4,
5038 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005039 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005040 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005041 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005042 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005043 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005044 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5045 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5046 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5047#endif
5048
5049 return v;
5050}
5051
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005052PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005053"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005054Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005055
5056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005057posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005058{
5059 int fd, res;
5060 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005061
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005062 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005063 return NULL;
5064 Py_BEGIN_ALLOW_THREADS
5065 res = fstatvfs(fd, &st);
5066 Py_END_ALLOW_THREADS
5067 if (res != 0)
5068 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005069
5070 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005071}
5072#endif /* HAVE_FSTATVFS */
5073
5074
5075#if defined(HAVE_STATVFS)
5076#include <sys/statvfs.h>
5077
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005078PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005079"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005080Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005081
5082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005083posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005084{
5085 char *path;
5086 int res;
5087 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005088 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005089 return NULL;
5090 Py_BEGIN_ALLOW_THREADS
5091 res = statvfs(path, &st);
5092 Py_END_ALLOW_THREADS
5093 if (res != 0)
5094 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005095
5096 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005097}
5098#endif /* HAVE_STATVFS */
5099
5100
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005101#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005102PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005103"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005104Return a unique name for a temporary file.\n\
5105The directory and a short may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005106or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005107
5108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005109posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005110{
5111 PyObject *result = NULL;
5112 char *dir = NULL;
5113 char *pfx = NULL;
5114 char *name;
5115
5116 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5117 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005118
5119 if (PyErr_Warn(PyExc_RuntimeWarning,
5120 "tempnam is a potential security risk to your program") < 0)
5121 return NULL;
5122
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005123#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005124 name = _tempnam(dir, pfx);
5125#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005126 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005127#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005128 if (name == NULL)
5129 return PyErr_NoMemory();
5130 result = PyString_FromString(name);
5131 free(name);
5132 return result;
5133}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005134#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005135
5136
5137#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005138PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005139"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005140Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005141
5142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005143posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005144{
5145 FILE *fp;
5146
5147 if (!PyArg_ParseTuple(args, ":tmpfile"))
5148 return NULL;
5149 fp = tmpfile();
5150 if (fp == NULL)
5151 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005152 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005153}
5154#endif
5155
5156
5157#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005158PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005159"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005160Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005161
5162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005163posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005164{
5165 char buffer[L_tmpnam];
5166 char *name;
5167
5168 if (!PyArg_ParseTuple(args, ":tmpnam"))
5169 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005170
5171 if (PyErr_Warn(PyExc_RuntimeWarning,
5172 "tmpnam is a potential security risk to your program") < 0)
5173 return NULL;
5174
Greg Wardb48bc172000-03-01 21:51:56 +00005175#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005176 name = tmpnam_r(buffer);
5177#else
5178 name = tmpnam(buffer);
5179#endif
5180 if (name == NULL) {
5181 PyErr_SetObject(PyExc_OSError,
5182 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005183#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005184 "unexpected NULL from tmpnam_r"
5185#else
5186 "unexpected NULL from tmpnam"
5187#endif
5188 ));
5189 return NULL;
5190 }
5191 return PyString_FromString(buffer);
5192}
5193#endif
5194
5195
Fred Drakec9680921999-12-13 16:37:25 +00005196/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5197 * It maps strings representing configuration variable names to
5198 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005199 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005200 * rarely-used constants. There are three separate tables that use
5201 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005202 *
5203 * This code is always included, even if none of the interfaces that
5204 * need it are included. The #if hackery needed to avoid it would be
5205 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005206 */
5207struct constdef {
5208 char *name;
5209 long value;
5210};
5211
Fred Drake12c6e2d1999-12-14 21:25:03 +00005212static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005213conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5214 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005215{
5216 if (PyInt_Check(arg)) {
5217 *valuep = PyInt_AS_LONG(arg);
5218 return 1;
5219 }
5220 if (PyString_Check(arg)) {
5221 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005222 size_t lo = 0;
5223 size_t mid;
5224 size_t hi = tablesize;
5225 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005226 char *confname = PyString_AS_STRING(arg);
5227 while (lo < hi) {
5228 mid = (lo + hi) / 2;
5229 cmp = strcmp(confname, table[mid].name);
5230 if (cmp < 0)
5231 hi = mid;
5232 else if (cmp > 0)
5233 lo = mid + 1;
5234 else {
5235 *valuep = table[mid].value;
5236 return 1;
5237 }
5238 }
5239 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5240 }
5241 else
5242 PyErr_SetString(PyExc_TypeError,
5243 "configuration names must be strings or integers");
5244 return 0;
5245}
5246
5247
5248#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5249static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005250#ifdef _PC_ABI_AIO_XFER_MAX
5251 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5252#endif
5253#ifdef _PC_ABI_ASYNC_IO
5254 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5255#endif
Fred Drakec9680921999-12-13 16:37:25 +00005256#ifdef _PC_ASYNC_IO
5257 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5258#endif
5259#ifdef _PC_CHOWN_RESTRICTED
5260 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5261#endif
5262#ifdef _PC_FILESIZEBITS
5263 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5264#endif
5265#ifdef _PC_LAST
5266 {"PC_LAST", _PC_LAST},
5267#endif
5268#ifdef _PC_LINK_MAX
5269 {"PC_LINK_MAX", _PC_LINK_MAX},
5270#endif
5271#ifdef _PC_MAX_CANON
5272 {"PC_MAX_CANON", _PC_MAX_CANON},
5273#endif
5274#ifdef _PC_MAX_INPUT
5275 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5276#endif
5277#ifdef _PC_NAME_MAX
5278 {"PC_NAME_MAX", _PC_NAME_MAX},
5279#endif
5280#ifdef _PC_NO_TRUNC
5281 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5282#endif
5283#ifdef _PC_PATH_MAX
5284 {"PC_PATH_MAX", _PC_PATH_MAX},
5285#endif
5286#ifdef _PC_PIPE_BUF
5287 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5288#endif
5289#ifdef _PC_PRIO_IO
5290 {"PC_PRIO_IO", _PC_PRIO_IO},
5291#endif
5292#ifdef _PC_SOCK_MAXBUF
5293 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5294#endif
5295#ifdef _PC_SYNC_IO
5296 {"PC_SYNC_IO", _PC_SYNC_IO},
5297#endif
5298#ifdef _PC_VDISABLE
5299 {"PC_VDISABLE", _PC_VDISABLE},
5300#endif
5301};
5302
Fred Drakec9680921999-12-13 16:37:25 +00005303static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005304conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005305{
5306 return conv_confname(arg, valuep, posix_constants_pathconf,
5307 sizeof(posix_constants_pathconf)
5308 / sizeof(struct constdef));
5309}
5310#endif
5311
5312#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005313PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005314"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005315Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005316If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005317
5318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005319posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005320{
5321 PyObject *result = NULL;
5322 int name, fd;
5323
Fred Drake12c6e2d1999-12-14 21:25:03 +00005324 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5325 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005326 long limit;
5327
5328 errno = 0;
5329 limit = fpathconf(fd, name);
5330 if (limit == -1 && errno != 0)
5331 posix_error();
5332 else
5333 result = PyInt_FromLong(limit);
5334 }
5335 return result;
5336}
5337#endif
5338
5339
5340#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005341PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005342"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005343Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005344If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005345
5346static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005347posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005348{
5349 PyObject *result = NULL;
5350 int name;
5351 char *path;
5352
5353 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5354 conv_path_confname, &name)) {
5355 long limit;
5356
5357 errno = 0;
5358 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005359 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005360 if (errno == EINVAL)
5361 /* could be a path or name problem */
5362 posix_error();
5363 else
5364 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005365 }
Fred Drakec9680921999-12-13 16:37:25 +00005366 else
5367 result = PyInt_FromLong(limit);
5368 }
5369 return result;
5370}
5371#endif
5372
5373#ifdef HAVE_CONFSTR
5374static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005375#ifdef _CS_ARCHITECTURE
5376 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5377#endif
5378#ifdef _CS_HOSTNAME
5379 {"CS_HOSTNAME", _CS_HOSTNAME},
5380#endif
5381#ifdef _CS_HW_PROVIDER
5382 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5383#endif
5384#ifdef _CS_HW_SERIAL
5385 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5386#endif
5387#ifdef _CS_INITTAB_NAME
5388 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5389#endif
Fred Drakec9680921999-12-13 16:37:25 +00005390#ifdef _CS_LFS64_CFLAGS
5391 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5392#endif
5393#ifdef _CS_LFS64_LDFLAGS
5394 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5395#endif
5396#ifdef _CS_LFS64_LIBS
5397 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5398#endif
5399#ifdef _CS_LFS64_LINTFLAGS
5400 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5401#endif
5402#ifdef _CS_LFS_CFLAGS
5403 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5404#endif
5405#ifdef _CS_LFS_LDFLAGS
5406 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5407#endif
5408#ifdef _CS_LFS_LIBS
5409 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5410#endif
5411#ifdef _CS_LFS_LINTFLAGS
5412 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5413#endif
Fred Draked86ed291999-12-15 15:34:33 +00005414#ifdef _CS_MACHINE
5415 {"CS_MACHINE", _CS_MACHINE},
5416#endif
Fred Drakec9680921999-12-13 16:37:25 +00005417#ifdef _CS_PATH
5418 {"CS_PATH", _CS_PATH},
5419#endif
Fred Draked86ed291999-12-15 15:34:33 +00005420#ifdef _CS_RELEASE
5421 {"CS_RELEASE", _CS_RELEASE},
5422#endif
5423#ifdef _CS_SRPC_DOMAIN
5424 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5425#endif
5426#ifdef _CS_SYSNAME
5427 {"CS_SYSNAME", _CS_SYSNAME},
5428#endif
5429#ifdef _CS_VERSION
5430 {"CS_VERSION", _CS_VERSION},
5431#endif
Fred Drakec9680921999-12-13 16:37:25 +00005432#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5433 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5434#endif
5435#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5436 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5437#endif
5438#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5439 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5440#endif
5441#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5442 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5443#endif
5444#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5445 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5446#endif
5447#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5448 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5449#endif
5450#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5451 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5452#endif
5453#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5454 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5455#endif
5456#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5457 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5458#endif
5459#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5460 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5461#endif
5462#ifdef _CS_XBS5_LP64_OFF64_LIBS
5463 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5464#endif
5465#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5466 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5467#endif
5468#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5469 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5470#endif
5471#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5472 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5473#endif
5474#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5475 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5476#endif
5477#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5478 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5479#endif
Fred Draked86ed291999-12-15 15:34:33 +00005480#ifdef _MIPS_CS_AVAIL_PROCESSORS
5481 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5482#endif
5483#ifdef _MIPS_CS_BASE
5484 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5485#endif
5486#ifdef _MIPS_CS_HOSTID
5487 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5488#endif
5489#ifdef _MIPS_CS_HW_NAME
5490 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5491#endif
5492#ifdef _MIPS_CS_NUM_PROCESSORS
5493 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5494#endif
5495#ifdef _MIPS_CS_OSREL_MAJ
5496 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5497#endif
5498#ifdef _MIPS_CS_OSREL_MIN
5499 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5500#endif
5501#ifdef _MIPS_CS_OSREL_PATCH
5502 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5503#endif
5504#ifdef _MIPS_CS_OS_NAME
5505 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5506#endif
5507#ifdef _MIPS_CS_OS_PROVIDER
5508 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5509#endif
5510#ifdef _MIPS_CS_PROCESSORS
5511 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5512#endif
5513#ifdef _MIPS_CS_SERIAL
5514 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5515#endif
5516#ifdef _MIPS_CS_VENDOR
5517 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5518#endif
Fred Drakec9680921999-12-13 16:37:25 +00005519};
5520
5521static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005522conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005523{
5524 return conv_confname(arg, valuep, posix_constants_confstr,
5525 sizeof(posix_constants_confstr)
5526 / sizeof(struct constdef));
5527}
5528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005529PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005530"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005531Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005532
5533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005534posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005535{
5536 PyObject *result = NULL;
5537 int name;
5538 char buffer[64];
5539
5540 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5541 int len = confstr(name, buffer, sizeof(buffer));
5542
Fred Drakec9680921999-12-13 16:37:25 +00005543 errno = 0;
5544 if (len == 0) {
5545 if (errno != 0)
5546 posix_error();
5547 else
5548 result = PyString_FromString("");
5549 }
5550 else {
5551 if (len >= sizeof(buffer)) {
5552 result = PyString_FromStringAndSize(NULL, len);
5553 if (result != NULL)
5554 confstr(name, PyString_AS_STRING(result), len+1);
5555 }
5556 else
5557 result = PyString_FromString(buffer);
5558 }
5559 }
5560 return result;
5561}
5562#endif
5563
5564
5565#ifdef HAVE_SYSCONF
5566static struct constdef posix_constants_sysconf[] = {
5567#ifdef _SC_2_CHAR_TERM
5568 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5569#endif
5570#ifdef _SC_2_C_BIND
5571 {"SC_2_C_BIND", _SC_2_C_BIND},
5572#endif
5573#ifdef _SC_2_C_DEV
5574 {"SC_2_C_DEV", _SC_2_C_DEV},
5575#endif
5576#ifdef _SC_2_C_VERSION
5577 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5578#endif
5579#ifdef _SC_2_FORT_DEV
5580 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5581#endif
5582#ifdef _SC_2_FORT_RUN
5583 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5584#endif
5585#ifdef _SC_2_LOCALEDEF
5586 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5587#endif
5588#ifdef _SC_2_SW_DEV
5589 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5590#endif
5591#ifdef _SC_2_UPE
5592 {"SC_2_UPE", _SC_2_UPE},
5593#endif
5594#ifdef _SC_2_VERSION
5595 {"SC_2_VERSION", _SC_2_VERSION},
5596#endif
Fred Draked86ed291999-12-15 15:34:33 +00005597#ifdef _SC_ABI_ASYNCHRONOUS_IO
5598 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5599#endif
5600#ifdef _SC_ACL
5601 {"SC_ACL", _SC_ACL},
5602#endif
Fred Drakec9680921999-12-13 16:37:25 +00005603#ifdef _SC_AIO_LISTIO_MAX
5604 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5605#endif
Fred Drakec9680921999-12-13 16:37:25 +00005606#ifdef _SC_AIO_MAX
5607 {"SC_AIO_MAX", _SC_AIO_MAX},
5608#endif
5609#ifdef _SC_AIO_PRIO_DELTA_MAX
5610 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5611#endif
5612#ifdef _SC_ARG_MAX
5613 {"SC_ARG_MAX", _SC_ARG_MAX},
5614#endif
5615#ifdef _SC_ASYNCHRONOUS_IO
5616 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5617#endif
5618#ifdef _SC_ATEXIT_MAX
5619 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5620#endif
Fred Draked86ed291999-12-15 15:34:33 +00005621#ifdef _SC_AUDIT
5622 {"SC_AUDIT", _SC_AUDIT},
5623#endif
Fred Drakec9680921999-12-13 16:37:25 +00005624#ifdef _SC_AVPHYS_PAGES
5625 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5626#endif
5627#ifdef _SC_BC_BASE_MAX
5628 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5629#endif
5630#ifdef _SC_BC_DIM_MAX
5631 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5632#endif
5633#ifdef _SC_BC_SCALE_MAX
5634 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5635#endif
5636#ifdef _SC_BC_STRING_MAX
5637 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5638#endif
Fred Draked86ed291999-12-15 15:34:33 +00005639#ifdef _SC_CAP
5640 {"SC_CAP", _SC_CAP},
5641#endif
Fred Drakec9680921999-12-13 16:37:25 +00005642#ifdef _SC_CHARCLASS_NAME_MAX
5643 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5644#endif
5645#ifdef _SC_CHAR_BIT
5646 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5647#endif
5648#ifdef _SC_CHAR_MAX
5649 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5650#endif
5651#ifdef _SC_CHAR_MIN
5652 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5653#endif
5654#ifdef _SC_CHILD_MAX
5655 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5656#endif
5657#ifdef _SC_CLK_TCK
5658 {"SC_CLK_TCK", _SC_CLK_TCK},
5659#endif
5660#ifdef _SC_COHER_BLKSZ
5661 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5662#endif
5663#ifdef _SC_COLL_WEIGHTS_MAX
5664 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5665#endif
5666#ifdef _SC_DCACHE_ASSOC
5667 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5668#endif
5669#ifdef _SC_DCACHE_BLKSZ
5670 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5671#endif
5672#ifdef _SC_DCACHE_LINESZ
5673 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5674#endif
5675#ifdef _SC_DCACHE_SZ
5676 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5677#endif
5678#ifdef _SC_DCACHE_TBLKSZ
5679 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5680#endif
5681#ifdef _SC_DELAYTIMER_MAX
5682 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5683#endif
5684#ifdef _SC_EQUIV_CLASS_MAX
5685 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5686#endif
5687#ifdef _SC_EXPR_NEST_MAX
5688 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5689#endif
5690#ifdef _SC_FSYNC
5691 {"SC_FSYNC", _SC_FSYNC},
5692#endif
5693#ifdef _SC_GETGR_R_SIZE_MAX
5694 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5695#endif
5696#ifdef _SC_GETPW_R_SIZE_MAX
5697 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5698#endif
5699#ifdef _SC_ICACHE_ASSOC
5700 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5701#endif
5702#ifdef _SC_ICACHE_BLKSZ
5703 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5704#endif
5705#ifdef _SC_ICACHE_LINESZ
5706 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5707#endif
5708#ifdef _SC_ICACHE_SZ
5709 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5710#endif
Fred Draked86ed291999-12-15 15:34:33 +00005711#ifdef _SC_INF
5712 {"SC_INF", _SC_INF},
5713#endif
Fred Drakec9680921999-12-13 16:37:25 +00005714#ifdef _SC_INT_MAX
5715 {"SC_INT_MAX", _SC_INT_MAX},
5716#endif
5717#ifdef _SC_INT_MIN
5718 {"SC_INT_MIN", _SC_INT_MIN},
5719#endif
5720#ifdef _SC_IOV_MAX
5721 {"SC_IOV_MAX", _SC_IOV_MAX},
5722#endif
Fred Draked86ed291999-12-15 15:34:33 +00005723#ifdef _SC_IP_SECOPTS
5724 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5725#endif
Fred Drakec9680921999-12-13 16:37:25 +00005726#ifdef _SC_JOB_CONTROL
5727 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5728#endif
Fred Draked86ed291999-12-15 15:34:33 +00005729#ifdef _SC_KERN_POINTERS
5730 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5731#endif
5732#ifdef _SC_KERN_SIM
5733 {"SC_KERN_SIM", _SC_KERN_SIM},
5734#endif
Fred Drakec9680921999-12-13 16:37:25 +00005735#ifdef _SC_LINE_MAX
5736 {"SC_LINE_MAX", _SC_LINE_MAX},
5737#endif
5738#ifdef _SC_LOGIN_NAME_MAX
5739 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5740#endif
5741#ifdef _SC_LOGNAME_MAX
5742 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5743#endif
5744#ifdef _SC_LONG_BIT
5745 {"SC_LONG_BIT", _SC_LONG_BIT},
5746#endif
Fred Draked86ed291999-12-15 15:34:33 +00005747#ifdef _SC_MAC
5748 {"SC_MAC", _SC_MAC},
5749#endif
Fred Drakec9680921999-12-13 16:37:25 +00005750#ifdef _SC_MAPPED_FILES
5751 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5752#endif
5753#ifdef _SC_MAXPID
5754 {"SC_MAXPID", _SC_MAXPID},
5755#endif
5756#ifdef _SC_MB_LEN_MAX
5757 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5758#endif
5759#ifdef _SC_MEMLOCK
5760 {"SC_MEMLOCK", _SC_MEMLOCK},
5761#endif
5762#ifdef _SC_MEMLOCK_RANGE
5763 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5764#endif
5765#ifdef _SC_MEMORY_PROTECTION
5766 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5767#endif
5768#ifdef _SC_MESSAGE_PASSING
5769 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5770#endif
Fred Draked86ed291999-12-15 15:34:33 +00005771#ifdef _SC_MMAP_FIXED_ALIGNMENT
5772 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5773#endif
Fred Drakec9680921999-12-13 16:37:25 +00005774#ifdef _SC_MQ_OPEN_MAX
5775 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5776#endif
5777#ifdef _SC_MQ_PRIO_MAX
5778 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5779#endif
Fred Draked86ed291999-12-15 15:34:33 +00005780#ifdef _SC_NACLS_MAX
5781 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5782#endif
Fred Drakec9680921999-12-13 16:37:25 +00005783#ifdef _SC_NGROUPS_MAX
5784 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5785#endif
5786#ifdef _SC_NL_ARGMAX
5787 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5788#endif
5789#ifdef _SC_NL_LANGMAX
5790 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5791#endif
5792#ifdef _SC_NL_MSGMAX
5793 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5794#endif
5795#ifdef _SC_NL_NMAX
5796 {"SC_NL_NMAX", _SC_NL_NMAX},
5797#endif
5798#ifdef _SC_NL_SETMAX
5799 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5800#endif
5801#ifdef _SC_NL_TEXTMAX
5802 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5803#endif
5804#ifdef _SC_NPROCESSORS_CONF
5805 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5806#endif
5807#ifdef _SC_NPROCESSORS_ONLN
5808 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5809#endif
Fred Draked86ed291999-12-15 15:34:33 +00005810#ifdef _SC_NPROC_CONF
5811 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5812#endif
5813#ifdef _SC_NPROC_ONLN
5814 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5815#endif
Fred Drakec9680921999-12-13 16:37:25 +00005816#ifdef _SC_NZERO
5817 {"SC_NZERO", _SC_NZERO},
5818#endif
5819#ifdef _SC_OPEN_MAX
5820 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5821#endif
5822#ifdef _SC_PAGESIZE
5823 {"SC_PAGESIZE", _SC_PAGESIZE},
5824#endif
5825#ifdef _SC_PAGE_SIZE
5826 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5827#endif
5828#ifdef _SC_PASS_MAX
5829 {"SC_PASS_MAX", _SC_PASS_MAX},
5830#endif
5831#ifdef _SC_PHYS_PAGES
5832 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5833#endif
5834#ifdef _SC_PII
5835 {"SC_PII", _SC_PII},
5836#endif
5837#ifdef _SC_PII_INTERNET
5838 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5839#endif
5840#ifdef _SC_PII_INTERNET_DGRAM
5841 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5842#endif
5843#ifdef _SC_PII_INTERNET_STREAM
5844 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5845#endif
5846#ifdef _SC_PII_OSI
5847 {"SC_PII_OSI", _SC_PII_OSI},
5848#endif
5849#ifdef _SC_PII_OSI_CLTS
5850 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5851#endif
5852#ifdef _SC_PII_OSI_COTS
5853 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5854#endif
5855#ifdef _SC_PII_OSI_M
5856 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5857#endif
5858#ifdef _SC_PII_SOCKET
5859 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5860#endif
5861#ifdef _SC_PII_XTI
5862 {"SC_PII_XTI", _SC_PII_XTI},
5863#endif
5864#ifdef _SC_POLL
5865 {"SC_POLL", _SC_POLL},
5866#endif
5867#ifdef _SC_PRIORITIZED_IO
5868 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5869#endif
5870#ifdef _SC_PRIORITY_SCHEDULING
5871 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5872#endif
5873#ifdef _SC_REALTIME_SIGNALS
5874 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5875#endif
5876#ifdef _SC_RE_DUP_MAX
5877 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5878#endif
5879#ifdef _SC_RTSIG_MAX
5880 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5881#endif
5882#ifdef _SC_SAVED_IDS
5883 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5884#endif
5885#ifdef _SC_SCHAR_MAX
5886 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5887#endif
5888#ifdef _SC_SCHAR_MIN
5889 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5890#endif
5891#ifdef _SC_SELECT
5892 {"SC_SELECT", _SC_SELECT},
5893#endif
5894#ifdef _SC_SEMAPHORES
5895 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5896#endif
5897#ifdef _SC_SEM_NSEMS_MAX
5898 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5899#endif
5900#ifdef _SC_SEM_VALUE_MAX
5901 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5902#endif
5903#ifdef _SC_SHARED_MEMORY_OBJECTS
5904 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5905#endif
5906#ifdef _SC_SHRT_MAX
5907 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5908#endif
5909#ifdef _SC_SHRT_MIN
5910 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5911#endif
5912#ifdef _SC_SIGQUEUE_MAX
5913 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5914#endif
5915#ifdef _SC_SIGRT_MAX
5916 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5917#endif
5918#ifdef _SC_SIGRT_MIN
5919 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5920#endif
Fred Draked86ed291999-12-15 15:34:33 +00005921#ifdef _SC_SOFTPOWER
5922 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5923#endif
Fred Drakec9680921999-12-13 16:37:25 +00005924#ifdef _SC_SPLIT_CACHE
5925 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5926#endif
5927#ifdef _SC_SSIZE_MAX
5928 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5929#endif
5930#ifdef _SC_STACK_PROT
5931 {"SC_STACK_PROT", _SC_STACK_PROT},
5932#endif
5933#ifdef _SC_STREAM_MAX
5934 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5935#endif
5936#ifdef _SC_SYNCHRONIZED_IO
5937 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5938#endif
5939#ifdef _SC_THREADS
5940 {"SC_THREADS", _SC_THREADS},
5941#endif
5942#ifdef _SC_THREAD_ATTR_STACKADDR
5943 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5944#endif
5945#ifdef _SC_THREAD_ATTR_STACKSIZE
5946 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5947#endif
5948#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5949 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5950#endif
5951#ifdef _SC_THREAD_KEYS_MAX
5952 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5953#endif
5954#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5955 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5956#endif
5957#ifdef _SC_THREAD_PRIO_INHERIT
5958 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5959#endif
5960#ifdef _SC_THREAD_PRIO_PROTECT
5961 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5962#endif
5963#ifdef _SC_THREAD_PROCESS_SHARED
5964 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5965#endif
5966#ifdef _SC_THREAD_SAFE_FUNCTIONS
5967 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5968#endif
5969#ifdef _SC_THREAD_STACK_MIN
5970 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5971#endif
5972#ifdef _SC_THREAD_THREADS_MAX
5973 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5974#endif
5975#ifdef _SC_TIMERS
5976 {"SC_TIMERS", _SC_TIMERS},
5977#endif
5978#ifdef _SC_TIMER_MAX
5979 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5980#endif
5981#ifdef _SC_TTY_NAME_MAX
5982 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5983#endif
5984#ifdef _SC_TZNAME_MAX
5985 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5986#endif
5987#ifdef _SC_T_IOV_MAX
5988 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5989#endif
5990#ifdef _SC_UCHAR_MAX
5991 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5992#endif
5993#ifdef _SC_UINT_MAX
5994 {"SC_UINT_MAX", _SC_UINT_MAX},
5995#endif
5996#ifdef _SC_UIO_MAXIOV
5997 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5998#endif
5999#ifdef _SC_ULONG_MAX
6000 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6001#endif
6002#ifdef _SC_USHRT_MAX
6003 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6004#endif
6005#ifdef _SC_VERSION
6006 {"SC_VERSION", _SC_VERSION},
6007#endif
6008#ifdef _SC_WORD_BIT
6009 {"SC_WORD_BIT", _SC_WORD_BIT},
6010#endif
6011#ifdef _SC_XBS5_ILP32_OFF32
6012 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6013#endif
6014#ifdef _SC_XBS5_ILP32_OFFBIG
6015 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6016#endif
6017#ifdef _SC_XBS5_LP64_OFF64
6018 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6019#endif
6020#ifdef _SC_XBS5_LPBIG_OFFBIG
6021 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6022#endif
6023#ifdef _SC_XOPEN_CRYPT
6024 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6025#endif
6026#ifdef _SC_XOPEN_ENH_I18N
6027 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6028#endif
6029#ifdef _SC_XOPEN_LEGACY
6030 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6031#endif
6032#ifdef _SC_XOPEN_REALTIME
6033 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6034#endif
6035#ifdef _SC_XOPEN_REALTIME_THREADS
6036 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6037#endif
6038#ifdef _SC_XOPEN_SHM
6039 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6040#endif
6041#ifdef _SC_XOPEN_UNIX
6042 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6043#endif
6044#ifdef _SC_XOPEN_VERSION
6045 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6046#endif
6047#ifdef _SC_XOPEN_XCU_VERSION
6048 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6049#endif
6050#ifdef _SC_XOPEN_XPG2
6051 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6052#endif
6053#ifdef _SC_XOPEN_XPG3
6054 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6055#endif
6056#ifdef _SC_XOPEN_XPG4
6057 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6058#endif
6059};
6060
6061static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006062conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006063{
6064 return conv_confname(arg, valuep, posix_constants_sysconf,
6065 sizeof(posix_constants_sysconf)
6066 / sizeof(struct constdef));
6067}
6068
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006069PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006070"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006071Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006072
6073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006074posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006075{
6076 PyObject *result = NULL;
6077 int name;
6078
6079 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6080 int value;
6081
6082 errno = 0;
6083 value = sysconf(name);
6084 if (value == -1 && errno != 0)
6085 posix_error();
6086 else
6087 result = PyInt_FromLong(value);
6088 }
6089 return result;
6090}
6091#endif
6092
6093
Fred Drakebec628d1999-12-15 18:31:10 +00006094/* This code is used to ensure that the tables of configuration value names
6095 * are in sorted order as required by conv_confname(), and also to build the
6096 * the exported dictionaries that are used to publish information about the
6097 * names available on the host platform.
6098 *
6099 * Sorting the table at runtime ensures that the table is properly ordered
6100 * when used, even for platforms we're not able to test on. It also makes
6101 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006102 */
Fred Drakebec628d1999-12-15 18:31:10 +00006103
6104static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006105cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006106{
6107 const struct constdef *c1 =
6108 (const struct constdef *) v1;
6109 const struct constdef *c2 =
6110 (const struct constdef *) v2;
6111
6112 return strcmp(c1->name, c2->name);
6113}
6114
6115static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006116setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006117 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006118{
Fred Drakebec628d1999-12-15 18:31:10 +00006119 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006120 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006121
6122 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6123 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006124 if (d == NULL)
6125 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006126
Barry Warsaw3155db32000-04-13 15:20:40 +00006127 for (i=0; i < tablesize; ++i) {
6128 PyObject *o = PyInt_FromLong(table[i].value);
6129 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6130 Py_XDECREF(o);
6131 Py_DECREF(d);
6132 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006133 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006134 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006135 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006136 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006137}
6138
Fred Drakebec628d1999-12-15 18:31:10 +00006139/* Return -1 on failure, 0 on success. */
6140static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006141setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006142{
6143#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006144 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006145 sizeof(posix_constants_pathconf)
6146 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006147 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006148 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006149#endif
6150#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006151 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006152 sizeof(posix_constants_confstr)
6153 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006154 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006155 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006156#endif
6157#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006158 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006159 sizeof(posix_constants_sysconf)
6160 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006161 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006162 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006163#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006164 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006165}
Fred Draked86ed291999-12-15 15:34:33 +00006166
6167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006168PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006169"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006170Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006172
6173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006174posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006175{
6176 if (!PyArg_ParseTuple(args, ":abort"))
6177 return NULL;
6178 abort();
6179 /*NOTREACHED*/
6180 Py_FatalError("abort() called from Python code didn't abort!");
6181 return NULL;
6182}
Fred Drakebec628d1999-12-15 18:31:10 +00006183
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006184#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006185PyDoc_STRVAR(win32_startfile__doc__,
6186"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006187\n\
6188This acts like double-clicking the file in Explorer, or giving the file\n\
6189name as an argument to the DOS \"start\" command: the file is opened\n\
6190with whatever application (if any) its extension is associated.\n\
6191\n\
6192startfile returns as soon as the associated application is launched.\n\
6193There is no option to wait for the application to close, and no way\n\
6194to retrieve the application's exit status.\n\
6195\n\
6196The filepath is relative to the current directory. If you want to use\n\
6197an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006198the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006199
6200static PyObject *
6201win32_startfile(PyObject *self, PyObject *args)
6202{
6203 char *filepath;
6204 HINSTANCE rc;
6205 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6206 return NULL;
6207 Py_BEGIN_ALLOW_THREADS
6208 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6209 Py_END_ALLOW_THREADS
6210 if (rc <= (HINSTANCE)32)
6211 return win32_error("startfile", filepath);
6212 Py_INCREF(Py_None);
6213 return Py_None;
6214}
6215#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006216
6217static PyMethodDef posix_methods[] = {
6218 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6219#ifdef HAVE_TTYNAME
6220 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6221#endif
6222 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6223 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006224#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006225 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006226#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006227#ifdef HAVE_CHROOT
6228 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6229#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006230#ifdef HAVE_CTERMID
6231 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6232#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006233#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006234 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006235#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006236#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006237 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006238#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006239 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6240 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6241 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006242#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006243 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006244#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006245#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006246 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006247#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006248 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6249 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6250 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006251#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006252 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006253#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006254#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006255 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006256#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006257 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006258#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006259 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006260#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006261 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6262 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6263 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006264#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006265 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006266#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006267 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006268#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006269 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6270 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006271#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006272#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006273 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6274 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006275#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006276#ifdef HAVE_FORK1
6277 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6278#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006279#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006280 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006281#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006282#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006283 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006284#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006285#ifdef HAVE_FORKPTY
6286 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6287#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006288#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006289 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006290#endif /* HAVE_GETEGID */
6291#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006292 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006293#endif /* HAVE_GETEUID */
6294#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006295 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006296#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006297#ifdef HAVE_GETGROUPS
6298 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6299#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006300 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006301#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006302 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006303#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006304#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006305 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006306#endif /* HAVE_GETPPID */
6307#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006308 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006309#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006310#ifdef HAVE_GETLOGIN
6311 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6312#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006313#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006314 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006315#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006316#ifdef HAVE_KILLPG
6317 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6318#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006319#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006320 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006321#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006322#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006323 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006324#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006325 {"popen2", win32_popen2, METH_VARARGS},
6326 {"popen3", win32_popen3, METH_VARARGS},
6327 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006328 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006329#else
6330#if defined(PYOS_OS2) && defined(PYCC_GCC)
6331 {"popen2", os2emx_popen2, METH_VARARGS},
6332 {"popen3", os2emx_popen3, METH_VARARGS},
6333 {"popen4", os2emx_popen4, METH_VARARGS},
6334#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006335#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006336#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006337#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006338 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006339#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006340#ifdef HAVE_SETEUID
6341 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6342#endif /* HAVE_SETEUID */
6343#ifdef HAVE_SETEGID
6344 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6345#endif /* HAVE_SETEGID */
6346#ifdef HAVE_SETREUID
6347 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6348#endif /* HAVE_SETREUID */
6349#ifdef HAVE_SETREGID
6350 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6351#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006352#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006353 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006354#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006355#ifdef HAVE_SETGROUPS
6356 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6357#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006358#ifdef HAVE_GETPGID
6359 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6360#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006361#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006362 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006363#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006364#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006366#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006367#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006368 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006369#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006370#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006371 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006372#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006373#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006374 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006375#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006376#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006377 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006378#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006379#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006380 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006381#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006382 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6383 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6384 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6385 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6386 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6387 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6388 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6389 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6390 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006391 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006392#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006393 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006394#endif
6395#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006396 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006397#endif
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006398#ifdef HAVE_MKNOD
6399 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6400#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006401#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006402 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006403#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006404#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006405 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006406#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006407#ifdef HAVE_UNSETENV
6408 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6409#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006410#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006411 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006412#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006413#ifdef HAVE_FCHDIR
6414 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6415#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006416#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006417 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006418#endif
6419#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006420 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006421#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006422#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006423#ifdef WCOREDUMP
6424 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6425#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006426#ifdef WIFCONTINUED
6427 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6428#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006429#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006430 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006431#endif /* WIFSTOPPED */
6432#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006433 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006434#endif /* WIFSIGNALED */
6435#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006436 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006437#endif /* WIFEXITED */
6438#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006439 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006440#endif /* WEXITSTATUS */
6441#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006442 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006443#endif /* WTERMSIG */
6444#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006445 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006446#endif /* WSTOPSIG */
6447#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006448#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006449 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006450#endif
6451#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006452 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006453#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006454#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006455 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6456#endif
6457#ifdef HAVE_TEMPNAM
6458 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6459#endif
6460#ifdef HAVE_TMPNAM
6461 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6462#endif
Fred Drakec9680921999-12-13 16:37:25 +00006463#ifdef HAVE_CONFSTR
6464 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6465#endif
6466#ifdef HAVE_SYSCONF
6467 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6468#endif
6469#ifdef HAVE_FPATHCONF
6470 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6471#endif
6472#ifdef HAVE_PATHCONF
6473 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6474#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006475 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006476#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006477 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6478#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006479 {NULL, NULL} /* Sentinel */
6480};
6481
6482
Barry Warsaw4a342091996-12-19 23:50:02 +00006483static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006484ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006485{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006486 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006487}
6488
Guido van Rossumd48f2521997-12-05 22:19:34 +00006489#if defined(PYOS_OS2)
6490/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006491static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006492{
6493 APIRET rc;
6494 ULONG values[QSV_MAX+1];
6495 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006496 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006497
6498 Py_BEGIN_ALLOW_THREADS
6499 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6500 Py_END_ALLOW_THREADS
6501
6502 if (rc != NO_ERROR) {
6503 os2_error(rc);
6504 return -1;
6505 }
6506
Fred Drake4d1e64b2002-04-15 19:40:07 +00006507 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6508 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6509 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6510 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6511 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6512 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6513 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006514
6515 switch (values[QSV_VERSION_MINOR]) {
6516 case 0: ver = "2.00"; break;
6517 case 10: ver = "2.10"; break;
6518 case 11: ver = "2.11"; break;
6519 case 30: ver = "3.00"; break;
6520 case 40: ver = "4.00"; break;
6521 case 50: ver = "5.00"; break;
6522 default:
Tim Peters885d4572001-11-28 20:27:42 +00006523 PyOS_snprintf(tmp, sizeof(tmp),
6524 "%d-%d", values[QSV_VERSION_MAJOR],
6525 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006526 ver = &tmp[0];
6527 }
6528
6529 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006530 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006531 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006532
6533 /* Add Indicator of Which Drive was Used to Boot the System */
6534 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6535 tmp[1] = ':';
6536 tmp[2] = '\0';
6537
Fred Drake4d1e64b2002-04-15 19:40:07 +00006538 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006539}
6540#endif
6541
Barry Warsaw4a342091996-12-19 23:50:02 +00006542static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006543all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006544{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006545#ifdef F_OK
6546 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006547#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006548#ifdef R_OK
6549 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006550#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006551#ifdef W_OK
6552 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006553#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006554#ifdef X_OK
6555 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006556#endif
Fred Drakec9680921999-12-13 16:37:25 +00006557#ifdef NGROUPS_MAX
6558 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6559#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006560#ifdef TMP_MAX
6561 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6562#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006563#ifdef WCONTINUED
6564 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6565#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006566#ifdef WNOHANG
6567 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006568#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006569#ifdef WUNTRACED
6570 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6571#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006572#ifdef O_RDONLY
6573 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6574#endif
6575#ifdef O_WRONLY
6576 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6577#endif
6578#ifdef O_RDWR
6579 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6580#endif
6581#ifdef O_NDELAY
6582 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6583#endif
6584#ifdef O_NONBLOCK
6585 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6586#endif
6587#ifdef O_APPEND
6588 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6589#endif
6590#ifdef O_DSYNC
6591 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6592#endif
6593#ifdef O_RSYNC
6594 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6595#endif
6596#ifdef O_SYNC
6597 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6598#endif
6599#ifdef O_NOCTTY
6600 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6601#endif
6602#ifdef O_CREAT
6603 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6604#endif
6605#ifdef O_EXCL
6606 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6607#endif
6608#ifdef O_TRUNC
6609 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6610#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006611#ifdef O_BINARY
6612 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6613#endif
6614#ifdef O_TEXT
6615 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6616#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006617#ifdef O_LARGEFILE
6618 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6619#endif
6620
Tim Peters5aa91602002-01-30 05:46:57 +00006621/* MS Windows */
6622#ifdef O_NOINHERIT
6623 /* Don't inherit in child processes. */
6624 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6625#endif
6626#ifdef _O_SHORT_LIVED
6627 /* Optimize for short life (keep in memory). */
6628 /* MS forgot to define this one with a non-underscore form too. */
6629 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6630#endif
6631#ifdef O_TEMPORARY
6632 /* Automatically delete when last handle is closed. */
6633 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6634#endif
6635#ifdef O_RANDOM
6636 /* Optimize for random access. */
6637 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6638#endif
6639#ifdef O_SEQUENTIAL
6640 /* Optimize for sequential access. */
6641 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6642#endif
6643
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006644/* GNU extensions. */
6645#ifdef O_DIRECT
6646 /* Direct disk access. */
6647 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6648#endif
6649#ifdef O_DIRECTORY
6650 /* Must be a directory. */
6651 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6652#endif
6653#ifdef O_NOFOLLOW
6654 /* Do not follow links. */
6655 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6656#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006657
Guido van Rossum246bc171999-02-01 23:54:31 +00006658#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006659#if defined(PYOS_OS2) && defined(PYCC_GCC)
6660 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6661 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6662 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6663 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6664 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6665 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6666 if (ins(d, "P_PM", (long)P_PM)) return -1;
6667 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6668 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6669 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6670 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6671 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6672 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6673 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6674 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6675 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6676 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6677 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6678 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6679 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6680#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006681 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6682 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6683 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6684 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6685 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006686#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006687#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006688
Guido van Rossumd48f2521997-12-05 22:19:34 +00006689#if defined(PYOS_OS2)
6690 if (insertvalues(d)) return -1;
6691#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006692 return 0;
6693}
6694
6695
Tim Peters5aa91602002-01-30 05:46:57 +00006696#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006697#define INITFUNC initnt
6698#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006699
6700#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006701#define INITFUNC initos2
6702#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006703
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006704#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006705#define INITFUNC initposix
6706#define MODNAME "posix"
6707#endif
6708
Guido van Rossum3886bb61998-12-04 18:50:17 +00006709DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006710INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006711{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006712 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006713
Fred Drake4d1e64b2002-04-15 19:40:07 +00006714 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006715 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006716 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006717
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006718 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006719 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006720 Py_XINCREF(v);
6721 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006722 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006723 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006724
Fred Drake4d1e64b2002-04-15 19:40:07 +00006725 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006726 return;
6727
Fred Drake4d1e64b2002-04-15 19:40:07 +00006728 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006729 return;
6730
Fred Drake4d1e64b2002-04-15 19:40:07 +00006731 Py_INCREF(PyExc_OSError);
6732 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006733
Guido van Rossumb3d39562000-01-31 18:41:26 +00006734#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006735 if (posix_putenv_garbage == NULL)
6736 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006737#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006738
Guido van Rossum14648392001-12-08 18:02:58 +00006739 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006740 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006741 Py_INCREF((PyObject*) &StatResultType);
6742 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006743
Guido van Rossum14648392001-12-08 18:02:58 +00006744 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006745 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006746 Py_INCREF((PyObject*) &StatVFSResultType);
6747 PyModule_AddObject(m, "statvfs_result",
6748 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006749}