blob: 9b7640f19c8c7b5884fc6a16f530e4c6fb4b48ba [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
19PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000020"This module provides access to operating system functionality that is\n\
21standardized by the C Standard and the POSIX standard (a thinly\n\
22disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000024
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000025#if defined(PYOS_OS2)
26#define INCL_DOS
27#define INCL_DOSERRORS
28#define INCL_DOSPROCESS
29#define INCL_NOPMAPI
30#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000031#if defined(PYCC_GCC)
32#include <ctype.h>
33#include <io.h>
34#include <stdio.h>
35#include <process.h>
36#include "osdefs.h"
37#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000038#endif
39
Guido van Rossumb6775db1994-08-01 11:34:53 +000040#include <sys/types.h>
41#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000042
Guido van Rossum36bc6801995-06-14 22:54:23 +000043#ifdef HAVE_SYS_WAIT_H
44#include <sys/wait.h> /* For WNOHANG */
45#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000046
Guido van Rossuma376cc51996-12-05 23:43:35 +000047#ifdef HAVE_SIGNAL_H
48#include <signal.h>
49#endif
50
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#ifdef HAVE_FCNTL_H
52#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000053#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000054
Guido van Rossuma6535fd2001-10-18 19:44:10 +000055#ifdef HAVE_GRP_H
56#include <grp.h>
57#endif
58
Guido van Rossuma4916fa1996-05-23 22:58:55 +000059/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000060/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000062#include <process.h>
63#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000064#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000065#define HAVE_GETCWD 1
66#define HAVE_OPENDIR 1
67#define HAVE_SYSTEM 1
68#if defined(__OS2__)
69#define HAVE_EXECV 1
70#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000071#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072#include <process.h>
73#else
74#ifdef __BORLANDC__ /* Borland compiler */
75#define HAVE_EXECV 1
76#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#define HAVE_OPENDIR 1
78#define HAVE_PIPE 1
79#define HAVE_POPEN 1
80#define HAVE_SYSTEM 1
81#define HAVE_WAIT 1
82#else
83#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000084#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +000085#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000086#define HAVE_EXECV 1
87#define HAVE_PIPE 1
88#define HAVE_POPEN 1
89#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000090#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000091#else
92#if defined(PYOS_OS2) && defined(PYCC_GCC)
93/* Everything needed is defined in PC/os2emx/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#else /* all other compilers */
95/* Unix functions that the configure script doesn't check for */
96#define HAVE_EXECV 1
97#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000098#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
99#define HAVE_FORK1 1
100#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_GETCWD 1
102#define HAVE_GETEGID 1
103#define HAVE_GETEUID 1
104#define HAVE_GETGID 1
105#define HAVE_GETPPID 1
106#define HAVE_GETUID 1
107#define HAVE_KILL 1
108#define HAVE_OPENDIR 1
109#define HAVE_PIPE 1
110#define HAVE_POPEN 1
111#define HAVE_SYSTEM 1
112#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000113#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000114#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#endif /* _MSC_VER */
116#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000117#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000118#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000119
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000121
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000122#if defined(sun) && !defined(__SVR4)
123/* SunOS 4.1.4 doesn't have prototypes for these: */
124extern int rename(const char *, const char *);
125extern int pclose(FILE *);
126extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000127extern int fsync(int);
128extern int lstat(const char *, struct stat *);
129extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000130#endif
131
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000132#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000135#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000136#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000138#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000139extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#endif
142#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int chdir(char *);
144extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000145#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(const char *);
147extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000149#ifdef __BORLANDC__
150extern int chmod(const char *, int);
151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000153#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int chown(const char *, uid_t, gid_t);
155extern char *getcwd(char *, int);
156extern char *strerror(int);
157extern int link(const char *, const char *);
158extern int rename(const char *, const char *);
159extern int stat(const char *, struct stat *);
160extern int unlink(const char *);
161extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000164#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000167#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000169
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172#ifdef HAVE_UTIME_H
173#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000174#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000176#ifdef HAVE_SYS_UTIME_H
177#include <sys/utime.h>
178#define HAVE_UTIME_H /* pretend we do for the rest of this file */
179#endif /* HAVE_SYS_UTIME_H */
180
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181#ifdef HAVE_SYS_TIMES_H
182#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000183#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184
185#ifdef HAVE_SYS_PARAM_H
186#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000187#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000188
189#ifdef HAVE_SYS_UTSNAME_H
190#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000191#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000193#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000195#define NAMLEN(dirent) strlen((dirent)->d_name)
196#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000197#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#include <direct.h>
199#define NAMLEN(dirent) strlen((dirent)->d_name)
200#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000202#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#endif
207#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#include <direct.h>
217#include <io.h>
218#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000219#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000220#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000222#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000224#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossumd48f2521997-12-05 22:19:34 +0000227#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230
Tim Petersbc2e10e2002-03-03 23:17:02 +0000231#ifndef MAXPATHLEN
232#define MAXPATHLEN 1024
233#endif /* MAXPATHLEN */
234
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000235#ifdef UNION_WAIT
236/* Emulate some macros on systems that have a union instead of macros */
237
238#ifndef WIFEXITED
239#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
240#endif
241
242#ifndef WEXITSTATUS
243#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
244#endif
245
246#ifndef WTERMSIG
247#define WTERMSIG(u_wait) ((u_wait).w_termsig)
248#endif
249
250#endif /* UNION_WAIT */
251
Greg Wardb48bc172000-03-01 21:51:56 +0000252/* Don't use the "_r" form if we don't need it (also, won't have a
253 prototype for it, at least on Solaris -- maybe others as well?). */
254#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
255#define USE_CTERMID_R
256#endif
257
258#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
259#define USE_TMPNAM_R
260#endif
261
Fred Drake699f3522000-06-29 21:12:41 +0000262/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000263#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000264#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000265# define STAT _stati64
266# define FSTAT _fstati64
267# define STRUCT_STAT struct _stati64
268#else
269# define STAT stat
270# define FSTAT fstat
271# define STRUCT_STAT struct stat
272#endif
273
Neal Norwitz3d949422002-04-20 13:46:43 +0000274#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
275#include <sys/mkdev.h>
276#endif
Fred Drake699f3522000-06-29 21:12:41 +0000277
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000279#ifdef WITH_NEXT_FRAMEWORK
280/* On Darwin/MacOSX a shared library or framework has no access to
281** environ directly, we must obtain it with _NSGetEnviron().
282*/
283#include <crt_externs.h>
284static char **environ;
285#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000287#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288
Barry Warsaw53699e91996-12-10 23:23:01 +0000289static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000290convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291{
Barry Warsaw53699e91996-12-10 23:23:01 +0000292 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000294 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 if (d == NULL)
296 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000297#ifdef WITH_NEXT_FRAMEWORK
298 if (environ == NULL)
299 environ = *_NSGetEnviron();
300#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301 if (environ == NULL)
302 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000303 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000305 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000306 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307 char *p = strchr(*e, '=');
308 if (p == NULL)
309 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000310 k = PyString_FromStringAndSize(*e, (int)(p-*e));
311 if (k == NULL) {
312 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000314 }
315 v = PyString_FromString(p+1);
316 if (v == NULL) {
317 PyErr_Clear();
318 Py_DECREF(k);
319 continue;
320 }
321 if (PyDict_GetItem(d, k) == NULL) {
322 if (PyDict_SetItem(d, k, v) != 0)
323 PyErr_Clear();
324 }
325 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000326 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000327 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000328#if defined(PYOS_OS2)
329 {
330 APIRET rc;
331 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
332
333 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000334 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000335 PyObject *v = PyString_FromString(buffer);
336 PyDict_SetItemString(d, "BEGINLIBPATH", v);
337 Py_DECREF(v);
338 }
339 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
340 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
341 PyObject *v = PyString_FromString(buffer);
342 PyDict_SetItemString(d, "ENDLIBPATH", v);
343 Py_DECREF(v);
344 }
345 }
346#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347 return d;
348}
349
350
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351/* Set a POSIX-specific error from errno, and return NULL */
352
Barry Warsawd58d7641998-07-23 16:14:40 +0000353static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000354posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000355{
Barry Warsawca74da41999-02-09 19:31:45 +0000356 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357}
Barry Warsawd58d7641998-07-23 16:14:40 +0000358static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000359posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000360{
Barry Warsawca74da41999-02-09 19:31:45 +0000361 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000362}
363
Mark Hammondef8b6542001-05-13 08:04:26 +0000364static PyObject *
365posix_error_with_allocated_filename(char* name)
366{
367 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
368 PyMem_Free(name);
369 return rc;
370}
371
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000372#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000373static PyObject *
374win32_error(char* function, char* filename)
375{
Mark Hammond33a6da92000-08-15 00:46:38 +0000376 /* XXX We should pass the function name along in the future.
377 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000378 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000379 Windows error object, which is non-trivial.
380 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000381 errno = GetLastError();
382 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000383 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000384 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000385 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000386}
387#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000388
Guido van Rossumd48f2521997-12-05 22:19:34 +0000389#if defined(PYOS_OS2)
390/**********************************************************************
391 * Helper Function to Trim and Format OS/2 Messages
392 **********************************************************************/
393 static void
394os2_formatmsg(char *msgbuf, int msglen, char *reason)
395{
396 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
397
398 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
399 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
400
401 while (lastc > msgbuf && isspace(*lastc))
402 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
403 }
404
405 /* Add Optional Reason Text */
406 if (reason) {
407 strcat(msgbuf, " : ");
408 strcat(msgbuf, reason);
409 }
410}
411
412/**********************************************************************
413 * Decode an OS/2 Operating System Error Code
414 *
415 * A convenience function to lookup an OS/2 error code and return a
416 * text message we can use to raise a Python exception.
417 *
418 * Notes:
419 * The messages for errors returned from the OS/2 kernel reside in
420 * the file OSO001.MSG in the \OS2 directory hierarchy.
421 *
422 **********************************************************************/
423 static char *
424os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
425{
426 APIRET rc;
427 ULONG msglen;
428
429 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
430 Py_BEGIN_ALLOW_THREADS
431 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
432 errorcode, "oso001.msg", &msglen);
433 Py_END_ALLOW_THREADS
434
435 if (rc == NO_ERROR)
436 os2_formatmsg(msgbuf, msglen, reason);
437 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000438 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000439 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000440
441 return msgbuf;
442}
443
444/* Set an OS/2-specific error and return NULL. OS/2 kernel
445 errors are not in a global variable e.g. 'errno' nor are
446 they congruent with posix error numbers. */
447
448static PyObject * os2_error(int code)
449{
450 char text[1024];
451 PyObject *v;
452
453 os2_strerror(text, sizeof(text), code, "");
454
455 v = Py_BuildValue("(is)", code, text);
456 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000457 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000458 Py_DECREF(v);
459 }
460 return NULL; /* Signal to Python that an Exception is Pending */
461}
462
463#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000464
465/* POSIX generic methods */
466
Barry Warsaw53699e91996-12-10 23:23:01 +0000467static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000468posix_fildes(PyObject *fdobj, int (*func)(int))
469{
470 int fd;
471 int res;
472 fd = PyObject_AsFileDescriptor(fdobj);
473 if (fd < 0)
474 return NULL;
475 Py_BEGIN_ALLOW_THREADS
476 res = (*func)(fd);
477 Py_END_ALLOW_THREADS
478 if (res < 0)
479 return posix_error();
480 Py_INCREF(Py_None);
481 return Py_None;
482}
Guido van Rossum21142a01999-01-08 21:05:37 +0000483
484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000485posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486{
Mark Hammondef8b6542001-05-13 08:04:26 +0000487 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000488 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000489 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000490 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000491 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000492 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000493 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000494 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000495 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000496 return posix_error_with_allocated_filename(path1);
497 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000498 Py_INCREF(Py_None);
499 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500}
501
Barry Warsaw53699e91996-12-10 23:23:01 +0000502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000503posix_2str(PyObject *args, char *format,
504 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000505{
Mark Hammondef8b6542001-05-13 08:04:26 +0000506 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000507 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000508 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000509 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000510 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000512 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000513 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000514 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000515 PyMem_Free(path1);
516 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000517 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000518 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000519 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000520 Py_INCREF(Py_None);
521 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000522}
523
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000525"stat_result: Result from stat or lstat.\n\n\
526This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000527 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000528or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
529\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000530Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000531they are available as attributes only.\n\
532\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000533See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000534
535static PyStructSequence_Field stat_result_fields[] = {
536 {"st_mode", "protection bits"},
537 {"st_ino", "inode"},
538 {"st_dev", "device"},
539 {"st_nlink", "number of hard links"},
540 {"st_uid", "user ID of owner"},
541 {"st_gid", "group ID of owner"},
542 {"st_size", "total size, in bytes"},
543 {"st_atime", "time of last access"},
544 {"st_mtime", "time of last modification"},
545 {"st_ctime", "time of last change"},
546#ifdef HAVE_ST_BLKSIZE
547 {"st_blksize", "blocksize for filesystem I/O"},
548#endif
549#ifdef HAVE_ST_BLOCKS
550 {"st_blocks", "number of blocks allocated"},
551#endif
552#ifdef HAVE_ST_RDEV
553 {"st_rdev", "device type (if inode device)"},
554#endif
555 {0}
556};
557
558#ifdef HAVE_ST_BLKSIZE
559#define ST_BLKSIZE_IDX 10
560#else
561#define ST_BLKSIZE_IDX 9
562#endif
563
564#ifdef HAVE_ST_BLOCKS
565#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
566#else
567#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
568#endif
569
570#ifdef HAVE_ST_RDEV
571#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
572#else
573#define ST_RDEV_IDX ST_BLOCKS_IDX
574#endif
575
576static PyStructSequence_Desc stat_result_desc = {
577 "stat_result", /* name */
578 stat_result__doc__, /* doc */
579 stat_result_fields,
580 10
581};
582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000583PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000584"statvfs_result: Result from statvfs or fstatvfs.\n\n\
585This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000586 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000587or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000588\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000589See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000590
591static PyStructSequence_Field statvfs_result_fields[] = {
592 {"f_bsize", },
593 {"f_frsize", },
594 {"f_blocks", },
595 {"f_bfree", },
596 {"f_bavail", },
597 {"f_files", },
598 {"f_ffree", },
599 {"f_favail", },
600 {"f_flag", },
601 {"f_namemax",},
602 {0}
603};
604
605static PyStructSequence_Desc statvfs_result_desc = {
606 "statvfs_result", /* name */
607 statvfs_result__doc__, /* doc */
608 statvfs_result_fields,
609 10
610};
611
612static PyTypeObject StatResultType;
613static PyTypeObject StatVFSResultType;
614
Tim Peters5aa91602002-01-30 05:46:57 +0000615/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000616 (used by posix_stat() and posix_fstat()) */
617static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000618_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000619{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000620 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000621 if (v == NULL)
622 return NULL;
623
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000624 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000625#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000626 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000627 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000628#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000629 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000630#endif
631#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000632 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000633 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000634#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000635 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000636#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000637 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
638 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
639 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000640#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000641 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000642 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000643#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000644 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000645#endif
646#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000647 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000648 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000649 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000650 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000651 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000652 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000653#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000654 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
655 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
656 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
657#endif
658
659#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000660 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000661 PyInt_FromLong((long)st.st_blksize));
662#endif
663#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000664 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000665 PyInt_FromLong((long)st.st_blocks));
666#endif
667#ifdef HAVE_ST_RDEV
668 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
669 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000670#endif
671
672 if (PyErr_Occurred()) {
673 Py_DECREF(v);
674 return NULL;
675 }
676
677 return v;
678}
679
Barry Warsaw53699e91996-12-10 23:23:01 +0000680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000681posix_do_stat(PyObject *self, PyObject *args, char *format,
682 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000683{
Fred Drake699f3522000-06-29 21:12:41 +0000684 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000685 char *path = NULL; /* pass this to stat; do not free() it */
686 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000687 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000688
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000689#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000690 int pathlen;
691 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000692#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000693
Tim Peters5aa91602002-01-30 05:46:57 +0000694 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000695 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000696 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000697 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000698
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000699#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000700 pathlen = strlen(path);
701 /* the library call can blow up if the file name is too long! */
702 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000703 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000704 errno = ENAMETOOLONG;
705 return posix_error();
706 }
707
Tim Peters500bd032001-12-19 19:05:01 +0000708 /* Remove trailing slash or backslash, unless it's the current
709 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
710 */
711 if (pathlen > 0 &&
712 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
713 /* It does end with a slash -- exempt the root drive cases. */
714 /* XXX UNC root drives should also be exempted? */
715 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
716 /* leave it alone */;
717 else {
718 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000719 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000720 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000721 path = pathcopy;
722 }
723 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000724#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000725
Barry Warsaw53699e91996-12-10 23:23:01 +0000726 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000727 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000728 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000729 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000730 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000731
Tim Peters500bd032001-12-19 19:05:01 +0000732 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000733 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000734}
735
736
737/* POSIX methods */
738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000739PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000740"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000741Use the real uid/gid to test for access to a path. Note that most\n\
742operations will use the effective uid/gid, therefore this routine can\n\
743be used in a suid/sgid environment to test if the invoking user has the\n\
744specified access to the path. The mode argument can be F_OK to test\n\
745existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000746
747static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000748posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000749{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000750 char *path;
751 int mode;
752 int res;
753
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000754 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000755 return NULL;
756 Py_BEGIN_ALLOW_THREADS
757 res = access(path, mode);
758 Py_END_ALLOW_THREADS
759 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000760}
761
Guido van Rossumd371ff11999-01-25 16:12:23 +0000762#ifndef F_OK
763#define F_OK 0
764#endif
765#ifndef R_OK
766#define R_OK 4
767#endif
768#ifndef W_OK
769#define W_OK 2
770#endif
771#ifndef X_OK
772#define X_OK 1
773#endif
774
775#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000776PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000777"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000778Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000779
780static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000781posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000782{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000783 int id;
784 char *ret;
785
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000786 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000787 return NULL;
788
Guido van Rossum94f6f721999-01-06 18:42:14 +0000789 ret = ttyname(id);
790 if (ret == NULL)
791 return(posix_error());
792 return(PyString_FromString(ret));
793}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000794#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000795
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000796#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000797PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000798"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000799Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000800
801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000802posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000803{
804 char *ret;
805 char buffer[L_ctermid];
806
807 if (!PyArg_ParseTuple(args, ":ctermid"))
808 return NULL;
809
Greg Wardb48bc172000-03-01 21:51:56 +0000810#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000811 ret = ctermid_r(buffer);
812#else
813 ret = ctermid(buffer);
814#endif
815 if (ret == NULL)
816 return(posix_error());
817 return(PyString_FromString(buffer));
818}
819#endif
820
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000821PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000822"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000823Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000824
Barry Warsaw53699e91996-12-10 23:23:01 +0000825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000826posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000827{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000828#if defined(PYOS_OS2) && defined(PYCC_GCC)
829 return posix_1str(args, "et:chdir", _chdir2);
830#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000831 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000832#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000833}
834
Fred Drake4d1e64b2002-04-15 19:40:07 +0000835#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000836PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000837"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +0000838Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000839opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +0000840
841static PyObject *
842posix_fchdir(PyObject *self, PyObject *fdobj)
843{
844 return posix_fildes(fdobj, fchdir);
845}
846#endif /* HAVE_FCHDIR */
847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000848
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000849PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000850"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000851Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000852
Barry Warsaw53699e91996-12-10 23:23:01 +0000853static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000854posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000855{
Mark Hammondef8b6542001-05-13 08:04:26 +0000856 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000857 int i;
858 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000859 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000860 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000861 return NULL;
862 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000863 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000864 Py_END_ALLOW_THREADS
865 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000866 return posix_error_with_allocated_filename(path);
867 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000868 Py_INCREF(Py_None);
869 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000870}
871
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000872
Martin v. Löwis244edc82001-10-04 22:44:26 +0000873#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000874PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000875"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000876Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +0000877
878static PyObject *
879posix_chroot(PyObject *self, PyObject *args)
880{
881 return posix_1str(args, "et:chroot", chroot);
882}
883#endif
884
Guido van Rossum21142a01999-01-08 21:05:37 +0000885#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000886PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000887"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000888force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000889
890static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000891posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000892{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000893 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000894}
895#endif /* HAVE_FSYNC */
896
897#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000898
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000899#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000900extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
901#endif
902
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000903PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000904"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +0000905force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000906 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000907
908static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000909posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000910{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000911 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000912}
913#endif /* HAVE_FDATASYNC */
914
915
Fredrik Lundh10723342000-07-10 16:38:09 +0000916#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000917PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000918"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000919Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000920
Barry Warsaw53699e91996-12-10 23:23:01 +0000921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000922posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000923{
Mark Hammondef8b6542001-05-13 08:04:26 +0000924 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000925 int uid, gid;
926 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000927 if (!PyArg_ParseTuple(args, "etii:chown",
928 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000929 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000930 return NULL;
931 Py_BEGIN_ALLOW_THREADS
932 res = chown(path, (uid_t) uid, (gid_t) gid);
933 Py_END_ALLOW_THREADS
934 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000935 return posix_error_with_allocated_filename(path);
936 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000937 Py_INCREF(Py_None);
938 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000939}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000940#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000941
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +0000942#ifdef HAVE_LCHOWN
943PyDoc_STRVAR(posix_lchown__doc__,
944"lchown(path, uid, gid)\n\n\
945Change the owner and group id of path to the numeric uid and gid.\n\
946This function will not follow symbolic links.");
947
948static PyObject *
949posix_lchown(PyObject *self, PyObject *args)
950{
951 char *path = NULL;
952 int uid, gid;
953 int res;
954 if (!PyArg_ParseTuple(args, "etii:lchown",
955 Py_FileSystemDefaultEncoding, &path,
956 &uid, &gid))
957 return NULL;
958 Py_BEGIN_ALLOW_THREADS
959 res = lchown(path, (uid_t) uid, (gid_t) gid);
960 Py_END_ALLOW_THREADS
961 if (res < 0)
962 return posix_error_with_allocated_filename(path);
963 PyMem_Free(path);
964 Py_INCREF(Py_None);
965 return Py_None;
966}
967#endif /* HAVE_LCHOWN */
968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000969
Guido van Rossum36bc6801995-06-14 22:54:23 +0000970#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000971PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000972"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000973Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000974
Barry Warsaw53699e91996-12-10 23:23:01 +0000975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000976posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000977{
978 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000979 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000980 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000981 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000982 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000983#if defined(PYOS_OS2) && defined(PYCC_GCC)
984 res = _getcwd2(buf, sizeof buf);
985#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000986 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000987#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000988 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000989 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000990 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000991 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000992}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000993#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000994
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000995
Guido van Rossumb6775db1994-08-01 11:34:53 +0000996#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000997PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000998"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000999Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001000
Barry Warsaw53699e91996-12-10 23:23:01 +00001001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001002posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001003{
Mark Hammondef8b6542001-05-13 08:04:26 +00001004 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001005}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001006#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001008
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001009PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001010"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001011Return a list containing the names of the entries in the directory.\n\
1012\n\
1013 path: path of directory to list\n\
1014\n\
1015The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001016entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001017
Barry Warsaw53699e91996-12-10 23:23:01 +00001018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001019posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001020{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001021 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001022 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001023#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001024
Barry Warsaw53699e91996-12-10 23:23:01 +00001025 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001026 HANDLE hFindFile;
1027 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001028 /* MAX_PATH characters could mean a bigger encoded string */
1029 char namebuf[MAX_PATH*2+5];
1030 char *bufptr = namebuf;
1031 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001032
Tim Peters5aa91602002-01-30 05:46:57 +00001033 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001034 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001035 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001036 if (len > 0) {
1037 char ch = namebuf[len-1];
1038 if (ch != SEP && ch != ALTSEP && ch != ':')
1039 namebuf[len++] = '/';
1040 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001041 strcpy(namebuf + len, "*.*");
1042
Barry Warsaw53699e91996-12-10 23:23:01 +00001043 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001044 return NULL;
1045
1046 hFindFile = FindFirstFile(namebuf, &FileData);
1047 if (hFindFile == INVALID_HANDLE_VALUE) {
1048 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001049 if (errno == ERROR_FILE_NOT_FOUND)
1050 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001051 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001052 }
1053 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001054 if (FileData.cFileName[0] == '.' &&
1055 (FileData.cFileName[1] == '\0' ||
1056 FileData.cFileName[1] == '.' &&
1057 FileData.cFileName[2] == '\0'))
1058 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001059 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001060 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001061 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001062 d = NULL;
1063 break;
1064 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001065 if (PyList_Append(d, v) != 0) {
1066 Py_DECREF(v);
1067 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001068 d = NULL;
1069 break;
1070 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001071 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001072 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1073
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001074 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001075 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001076
1077 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001078
Tim Peters0bb44a42000-09-15 07:44:49 +00001079#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001080
1081#ifndef MAX_PATH
1082#define MAX_PATH CCHMAXPATH
1083#endif
1084 char *name, *pt;
1085 int len;
1086 PyObject *d, *v;
1087 char namebuf[MAX_PATH+5];
1088 HDIR hdir = 1;
1089 ULONG srchcnt = 1;
1090 FILEFINDBUF3 ep;
1091 APIRET rc;
1092
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001093 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001094 return NULL;
1095 if (len >= MAX_PATH) {
1096 PyErr_SetString(PyExc_ValueError, "path too long");
1097 return NULL;
1098 }
1099 strcpy(namebuf, name);
1100 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001101 if (*pt == ALTSEP)
1102 *pt = SEP;
1103 if (namebuf[len-1] != SEP)
1104 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001105 strcpy(namebuf + len, "*.*");
1106
1107 if ((d = PyList_New(0)) == NULL)
1108 return NULL;
1109
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001110 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1111 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001112 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001113 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1114 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1115 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001116
1117 if (rc != NO_ERROR) {
1118 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001119 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001120 }
1121
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001122 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001123 do {
1124 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001125 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001126 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001127
1128 strcpy(namebuf, ep.achName);
1129
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001130 /* Leave Case of Name Alone -- In Native Form */
1131 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001132
1133 v = PyString_FromString(namebuf);
1134 if (v == NULL) {
1135 Py_DECREF(d);
1136 d = NULL;
1137 break;
1138 }
1139 if (PyList_Append(d, v) != 0) {
1140 Py_DECREF(v);
1141 Py_DECREF(d);
1142 d = NULL;
1143 break;
1144 }
1145 Py_DECREF(v);
1146 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1147 }
1148
1149 return d;
1150#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001151
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001152 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001153 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001154 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001155 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001156 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001157 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001158 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001159 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001160 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001161 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162 closedir(dirp);
1163 return NULL;
1164 }
1165 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001166 if (ep->d_name[0] == '.' &&
1167 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001168 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001169 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001170 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001172 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001173 d = NULL;
1174 break;
1175 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001176 if (PyList_Append(d, v) != 0) {
1177 Py_DECREF(v);
1178 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001179 d = NULL;
1180 break;
1181 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001182 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001183 }
1184 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001185
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001186 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001187
Tim Peters0bb44a42000-09-15 07:44:49 +00001188#endif /* which OS */
1189} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001190
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001191#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001192/* A helper function for abspath on win32 */
1193static PyObject *
1194posix__getfullpathname(PyObject *self, PyObject *args)
1195{
1196 /* assume encoded strings wont more than double no of chars */
1197 char inbuf[MAX_PATH*2];
1198 char *inbufp = inbuf;
1199 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1200 char outbuf[MAX_PATH*2];
1201 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001202 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1203 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001204 &insize))
1205 return NULL;
1206 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1207 outbuf, &temp))
1208 return win32_error("GetFullPathName", inbuf);
1209 return PyString_FromString(outbuf);
1210} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001211#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001212
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001213PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001214"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001215Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001216
Barry Warsaw53699e91996-12-10 23:23:01 +00001217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001218posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001219{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001220 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001221 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001222 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001223 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001224 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001225 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001226 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001227#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001228 res = mkdir(path);
1229#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001230 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001231#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001232 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001233 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001234 return posix_error_with_allocated_filename(path);
1235 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001236 Py_INCREF(Py_None);
1237 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001238}
1239
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001240
Guido van Rossumb6775db1994-08-01 11:34:53 +00001241#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001242#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1243#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1244#include <sys/resource.h>
1245#endif
1246#endif
1247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001248PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001249"nice(inc) -> new_priority\n\n\
1250Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001251
Barry Warsaw53699e91996-12-10 23:23:01 +00001252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001253posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001254{
1255 int increment, value;
1256
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001257 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001258 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001259
1260 /* There are two flavours of 'nice': one that returns the new
1261 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001262 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1263 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001264
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001265 If we are of the nice family that returns the new priority, we
1266 need to clear errno before the call, and check if errno is filled
1267 before calling posix_error() on a returnvalue of -1, because the
1268 -1 may be the actual new priority! */
1269
1270 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001271 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001272#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001273 if (value == 0)
1274 value = getpriority(PRIO_PROCESS, 0);
1275#endif
1276 if (value == -1 && errno != 0)
1277 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001278 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001279 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001280}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001281#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001283
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001284PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001285"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001286Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001287
Barry Warsaw53699e91996-12-10 23:23:01 +00001288static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001289posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001290{
Mark Hammondef8b6542001-05-13 08:04:26 +00001291 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292}
1293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001294
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001295PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001296"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001297Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001298
Barry Warsaw53699e91996-12-10 23:23:01 +00001299static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001300posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301{
Mark Hammondef8b6542001-05-13 08:04:26 +00001302 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303}
1304
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001305
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001306PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001307"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001308Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001309
Barry Warsaw53699e91996-12-10 23:23:01 +00001310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001311posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312{
Mark Hammondef8b6542001-05-13 08:04:26 +00001313 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314}
1315
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001316
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001317#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001318PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001319"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001320Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001321
Barry Warsaw53699e91996-12-10 23:23:01 +00001322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001323posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001324{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001325 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001326 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001327 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001328 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001329 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001330 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001331 Py_END_ALLOW_THREADS
1332 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001334#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001335
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001336
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001337PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001338"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001339Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001340
Barry Warsaw53699e91996-12-10 23:23:01 +00001341static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001342posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001343{
1344 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001345 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001347 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001348 if (i < 0)
1349 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001350 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001351}
1352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001353
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001354PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001355"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001356Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001357
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001358PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001359"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001360Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001361
Barry Warsaw53699e91996-12-10 23:23:01 +00001362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001363posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364{
Mark Hammondef8b6542001-05-13 08:04:26 +00001365 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001366}
1367
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001368
Guido van Rossumb6775db1994-08-01 11:34:53 +00001369#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001370PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001371"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001372Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001373
Barry Warsaw53699e91996-12-10 23:23:01 +00001374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001375posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001376{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001377 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001378 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001379 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001380 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001381 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001382 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001383 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001384 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001385 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001386 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001387 u.sysname,
1388 u.nodename,
1389 u.release,
1390 u.version,
1391 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001392}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001393#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001394
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001395
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001396PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001397"utime(path, (atime, utime))\n\
1398utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001399Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001400second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001401
Barry Warsaw53699e91996-12-10 23:23:01 +00001402static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001403posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001404{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001405 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001406 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001407 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001408 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001409
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001410/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001411#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001412 struct utimbuf buf;
1413#define ATIME buf.actime
1414#define MTIME buf.modtime
1415#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001416#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001417 time_t buf[2];
1418#define ATIME buf[0]
1419#define MTIME buf[1]
1420#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001421#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001422
Barry Warsaw3cef8562000-05-01 16:17:24 +00001423 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001424 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001425 if (arg == Py_None) {
1426 /* optional time values not given */
1427 Py_BEGIN_ALLOW_THREADS
1428 res = utime(path, NULL);
1429 Py_END_ALLOW_THREADS
1430 }
Neal Norwitzcfa1f522002-07-30 12:27:43 +00001431 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001432 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001433 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001434 return NULL;
1435 }
1436 else {
1437 ATIME = atime;
1438 MTIME = mtime;
1439 Py_BEGIN_ALLOW_THREADS
1440 res = utime(path, UTIME_ARG);
1441 Py_END_ALLOW_THREADS
1442 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001443 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001444 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001445 Py_INCREF(Py_None);
1446 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001447#undef UTIME_ARG
1448#undef ATIME
1449#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001450}
1451
Guido van Rossum85e3b011991-06-03 12:42:10 +00001452
Guido van Rossum3b066191991-06-04 19:40:25 +00001453/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001454
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001455PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001456"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001457Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001458
Barry Warsaw53699e91996-12-10 23:23:01 +00001459static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001460posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001461{
1462 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001463 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001464 return NULL;
1465 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001466 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001467}
1468
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001469
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001470#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001471PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001472"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001473Execute an executable path with arguments, replacing current process.\n\
1474\n\
1475 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001476 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001477
Barry Warsaw53699e91996-12-10 23:23:01 +00001478static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001479posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001480{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001481 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001482 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001483 char **argvlist;
1484 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001485 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001486
Guido van Rossum89b33251993-10-22 14:26:06 +00001487 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001488 argv is a list or tuple of strings. */
1489
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001490 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001491 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001492 if (PyList_Check(argv)) {
1493 argc = PyList_Size(argv);
1494 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001495 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001496 else if (PyTuple_Check(argv)) {
1497 argc = PyTuple_Size(argv);
1498 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001499 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001500 else {
Fred Drake661ea262000-10-24 19:57:45 +00001501 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001502 return NULL;
1503 }
1504
1505 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001506 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001507 return NULL;
1508 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001509
Barry Warsaw53699e91996-12-10 23:23:01 +00001510 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001511 if (argvlist == NULL)
1512 return NULL;
1513 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001514 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1515 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001516 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001517 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001518 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001519
Guido van Rossum85e3b011991-06-03 12:42:10 +00001520 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001521 }
1522 argvlist[argc] = NULL;
1523
Guido van Rossumb6775db1994-08-01 11:34:53 +00001524#ifdef BAD_EXEC_PROTOTYPES
1525 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001526#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001527 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001528#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001529
Guido van Rossum85e3b011991-06-03 12:42:10 +00001530 /* If we get here it's definitely an error */
1531
Barry Warsaw53699e91996-12-10 23:23:01 +00001532 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001533 return posix_error();
1534}
1535
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001536
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001537PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001538"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001539Execute a path with arguments and environment, replacing current process.\n\
1540\n\
1541 path: path of executable file\n\
1542 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001543 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001544
Barry Warsaw53699e91996-12-10 23:23:01 +00001545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001546posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001547{
1548 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001549 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001550 char **argvlist;
1551 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001552 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001553 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001554 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001555
1556 /* execve has three arguments: (path, argv, env), where
1557 argv is a list or tuple of strings and env is a dictionary
1558 like posix.environ. */
1559
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001560 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001561 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001562 if (PyList_Check(argv)) {
1563 argc = PyList_Size(argv);
1564 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001565 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001566 else if (PyTuple_Check(argv)) {
1567 argc = PyTuple_Size(argv);
1568 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001569 }
1570 else {
Fred Drake661ea262000-10-24 19:57:45 +00001571 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001572 return NULL;
1573 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001574 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001575 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001576 return NULL;
1577 }
1578
Guido van Rossum50422b42000-04-26 20:34:28 +00001579 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001580 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001581 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001582 return NULL;
1583 }
1584
Barry Warsaw53699e91996-12-10 23:23:01 +00001585 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001586 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001587 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001588 return NULL;
1589 }
1590 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001591 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001592 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001593 &argvlist[i]))
1594 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001595 goto fail_1;
1596 }
1597 }
1598 argvlist[argc] = NULL;
1599
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001600 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001601 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001602 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001603 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001604 goto fail_1;
1605 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001606 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001607 keys = PyMapping_Keys(env);
1608 vals = PyMapping_Values(env);
1609 if (!keys || !vals)
1610 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001611
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001612 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001613 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001614 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001615
1616 key = PyList_GetItem(keys, pos);
1617 val = PyList_GetItem(vals, pos);
1618 if (!key || !val)
1619 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001620
Fred Drake661ea262000-10-24 19:57:45 +00001621 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1622 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001623 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001624 goto fail_2;
1625 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001626
1627#if defined(PYOS_OS2)
1628 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1629 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1630#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001631 len = PyString_Size(key) + PyString_Size(val) + 2;
1632 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001633 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001634 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001635 goto fail_2;
1636 }
Tim Petersc8996f52001-12-03 20:41:00 +00001637 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001638 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001639#if defined(PYOS_OS2)
1640 }
1641#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001642 }
1643 envlist[envc] = 0;
1644
Guido van Rossumb6775db1994-08-01 11:34:53 +00001645
1646#ifdef BAD_EXEC_PROTOTYPES
1647 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001648#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001649 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001650#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001651
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001652 /* If we get here it's definitely an error */
1653
1654 (void) posix_error();
1655
1656 fail_2:
1657 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001658 PyMem_DEL(envlist[envc]);
1659 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001660 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001661 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001662 Py_XDECREF(vals);
1663 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001664 return NULL;
1665}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001666#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001668
Guido van Rossuma1065681999-01-25 23:20:23 +00001669#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001670PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001671"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001672Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001673\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001674 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001675 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001676 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001677
1678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001679posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001680{
1681 char *path;
1682 PyObject *argv;
1683 char **argvlist;
1684 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001685 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001686 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001687
1688 /* spawnv has three arguments: (mode, path, argv), where
1689 argv is a list or tuple of strings. */
1690
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001691 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001692 return NULL;
1693 if (PyList_Check(argv)) {
1694 argc = PyList_Size(argv);
1695 getitem = PyList_GetItem;
1696 }
1697 else if (PyTuple_Check(argv)) {
1698 argc = PyTuple_Size(argv);
1699 getitem = PyTuple_GetItem;
1700 }
1701 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001702 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001703 return NULL;
1704 }
1705
1706 argvlist = PyMem_NEW(char *, argc+1);
1707 if (argvlist == NULL)
1708 return NULL;
1709 for (i = 0; i < argc; i++) {
1710 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1711 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001712 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001713 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001714 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001715 }
1716 }
1717 argvlist[argc] = NULL;
1718
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001719#if defined(PYOS_OS2) && defined(PYCC_GCC)
1720 Py_BEGIN_ALLOW_THREADS
1721 spawnval = spawnv(mode, path, argvlist);
1722 Py_END_ALLOW_THREADS
1723#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001724 if (mode == _OLD_P_OVERLAY)
1725 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001726
Tim Peters25059d32001-12-07 20:35:43 +00001727 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001728 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001729 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001730#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001731
Guido van Rossuma1065681999-01-25 23:20:23 +00001732 PyMem_DEL(argvlist);
1733
Fred Drake699f3522000-06-29 21:12:41 +00001734 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001735 return posix_error();
1736 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001737#if SIZEOF_LONG == SIZEOF_VOID_P
1738 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001739#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001740 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001741#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001742}
1743
1744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001745PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001746"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001747Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001748\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001749 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001750 path: path of executable file\n\
1751 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001752 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001753
1754static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001755posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001756{
1757 char *path;
1758 PyObject *argv, *env;
1759 char **argvlist;
1760 char **envlist;
1761 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1762 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001763 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001764 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001765
1766 /* spawnve has four arguments: (mode, path, argv, env), where
1767 argv is a list or tuple of strings and env is a dictionary
1768 like posix.environ. */
1769
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001770 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001771 return NULL;
1772 if (PyList_Check(argv)) {
1773 argc = PyList_Size(argv);
1774 getitem = PyList_GetItem;
1775 }
1776 else if (PyTuple_Check(argv)) {
1777 argc = PyTuple_Size(argv);
1778 getitem = PyTuple_GetItem;
1779 }
1780 else {
Fred Drake661ea262000-10-24 19:57:45 +00001781 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001782 return NULL;
1783 }
1784 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001785 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001786 return NULL;
1787 }
1788
1789 argvlist = PyMem_NEW(char *, argc+1);
1790 if (argvlist == NULL) {
1791 PyErr_NoMemory();
1792 return NULL;
1793 }
1794 for (i = 0; i < argc; i++) {
1795 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001796 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001797 &argvlist[i]))
1798 {
1799 goto fail_1;
1800 }
1801 }
1802 argvlist[argc] = NULL;
1803
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001804 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001805 envlist = PyMem_NEW(char *, i + 1);
1806 if (envlist == NULL) {
1807 PyErr_NoMemory();
1808 goto fail_1;
1809 }
1810 envc = 0;
1811 keys = PyMapping_Keys(env);
1812 vals = PyMapping_Values(env);
1813 if (!keys || !vals)
1814 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001815
Guido van Rossuma1065681999-01-25 23:20:23 +00001816 for (pos = 0; pos < i; pos++) {
1817 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001818 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001819
1820 key = PyList_GetItem(keys, pos);
1821 val = PyList_GetItem(vals, pos);
1822 if (!key || !val)
1823 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001824
Fred Drake661ea262000-10-24 19:57:45 +00001825 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1826 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001827 {
1828 goto fail_2;
1829 }
Tim Petersc8996f52001-12-03 20:41:00 +00001830 len = PyString_Size(key) + PyString_Size(val) + 2;
1831 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001832 if (p == NULL) {
1833 PyErr_NoMemory();
1834 goto fail_2;
1835 }
Tim Petersc8996f52001-12-03 20:41:00 +00001836 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001837 envlist[envc++] = p;
1838 }
1839 envlist[envc] = 0;
1840
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001841#if defined(PYOS_OS2) && defined(PYCC_GCC)
1842 Py_BEGIN_ALLOW_THREADS
1843 spawnval = spawnve(mode, path, argvlist, envlist);
1844 Py_END_ALLOW_THREADS
1845#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001846 if (mode == _OLD_P_OVERLAY)
1847 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001848
1849 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001850 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001851 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001852#endif
Tim Peters25059d32001-12-07 20:35:43 +00001853
Fred Drake699f3522000-06-29 21:12:41 +00001854 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001855 (void) posix_error();
1856 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001857#if SIZEOF_LONG == SIZEOF_VOID_P
1858 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001859#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001860 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001861#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001862
1863 fail_2:
1864 while (--envc >= 0)
1865 PyMem_DEL(envlist[envc]);
1866 PyMem_DEL(envlist);
1867 fail_1:
1868 PyMem_DEL(argvlist);
1869 Py_XDECREF(vals);
1870 Py_XDECREF(keys);
1871 return res;
1872}
1873#endif /* HAVE_SPAWNV */
1874
1875
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001876#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001877PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001878"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001879Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1880\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001881Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001882
1883static PyObject *
1884posix_fork1(self, args)
1885 PyObject *self;
1886 PyObject *args;
1887{
1888 int pid;
1889 if (!PyArg_ParseTuple(args, ":fork1"))
1890 return NULL;
1891 pid = fork1();
1892 if (pid == -1)
1893 return posix_error();
1894 PyOS_AfterFork();
1895 return PyInt_FromLong((long)pid);
1896}
1897#endif
1898
1899
Guido van Rossumad0ee831995-03-01 10:34:45 +00001900#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001901PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001902"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001903Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001904Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001905
Barry Warsaw53699e91996-12-10 23:23:01 +00001906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001907posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001908{
1909 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001910 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001911 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001912 pid = fork();
1913 if (pid == -1)
1914 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001915 if (pid == 0)
1916 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001917 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001918}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001919#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001920
Fred Drake8cef4cf2000-06-28 16:40:38 +00001921#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1922#ifdef HAVE_PTY_H
1923#include <pty.h>
1924#else
1925#ifdef HAVE_LIBUTIL_H
1926#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001927#endif /* HAVE_LIBUTIL_H */
1928#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001929#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001930
Thomas Wouters70c21a12000-07-14 14:28:33 +00001931#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001932PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001933"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001934Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001935
1936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001937posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001938{
1939 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001940#ifndef HAVE_OPENPTY
1941 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001942#endif
1943
Fred Drake8cef4cf2000-06-28 16:40:38 +00001944 if (!PyArg_ParseTuple(args, ":openpty"))
1945 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001946
1947#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001948 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1949 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001950#else
1951 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1952 if (slave_name == NULL)
1953 return posix_error();
1954
1955 slave_fd = open(slave_name, O_RDWR);
1956 if (slave_fd < 0)
1957 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001958#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001959
Fred Drake8cef4cf2000-06-28 16:40:38 +00001960 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001961
Fred Drake8cef4cf2000-06-28 16:40:38 +00001962}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001963#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001964
1965#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001966PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001967"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00001968Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1969Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001971
1972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001973posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001974{
1975 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00001976
Fred Drake8cef4cf2000-06-28 16:40:38 +00001977 if (!PyArg_ParseTuple(args, ":forkpty"))
1978 return NULL;
1979 pid = forkpty(&master_fd, NULL, NULL, NULL);
1980 if (pid == -1)
1981 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001982 if (pid == 0)
1983 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001984 return Py_BuildValue("(ii)", pid, master_fd);
1985}
1986#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001987
Guido van Rossumad0ee831995-03-01 10:34:45 +00001988#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001989PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001990"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001991Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001992
Barry Warsaw53699e91996-12-10 23:23:01 +00001993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001994posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001995{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001996 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001997 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001998 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001999}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002000#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002002
Guido van Rossumad0ee831995-03-01 10:34:45 +00002003#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002004PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002005"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002006Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002007
Barry Warsaw53699e91996-12-10 23:23:01 +00002008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002009posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002010{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002011 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002012 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002013 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002014}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002015#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002017
Guido van Rossumad0ee831995-03-01 10:34:45 +00002018#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002019PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002020"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002021Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002022
Barry Warsaw53699e91996-12-10 23:23:01 +00002023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002024posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002025{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002026 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002027 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002028 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002029}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002030#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002034"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002035Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002036
Barry Warsaw53699e91996-12-10 23:23:01 +00002037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002038posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002039{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002040 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002041 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002042 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002043}
2044
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002045
Fred Drakec9680921999-12-13 16:37:25 +00002046#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002048"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002049Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002050
2051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002052posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002053{
2054 PyObject *result = NULL;
2055
2056 if (PyArg_ParseTuple(args, ":getgroups")) {
2057#ifdef NGROUPS_MAX
2058#define MAX_GROUPS NGROUPS_MAX
2059#else
2060 /* defined to be 16 on Solaris7, so this should be a small number */
2061#define MAX_GROUPS 64
2062#endif
2063 gid_t grouplist[MAX_GROUPS];
2064 int n;
2065
2066 n = getgroups(MAX_GROUPS, grouplist);
2067 if (n < 0)
2068 posix_error();
2069 else {
2070 result = PyList_New(n);
2071 if (result != NULL) {
2072 PyObject *o;
2073 int i;
2074 for (i = 0; i < n; ++i) {
2075 o = PyInt_FromLong((long)grouplist[i]);
2076 if (o == NULL) {
2077 Py_DECREF(result);
2078 result = NULL;
2079 break;
2080 }
2081 PyList_SET_ITEM(result, i, o);
2082 }
2083 }
2084 }
2085 }
2086 return result;
2087}
2088#endif
2089
Martin v. Löwis606edc12002-06-13 21:09:11 +00002090#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002091PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002092"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002093Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002094
2095static PyObject *
2096posix_getpgid(PyObject *self, PyObject *args)
2097{
2098 int pid, pgid;
2099 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2100 return NULL;
2101 pgid = getpgid(pid);
2102 if (pgid < 0)
2103 return posix_error();
2104 return PyInt_FromLong((long)pgid);
2105}
2106#endif /* HAVE_GETPGID */
2107
2108
Guido van Rossumb6775db1994-08-01 11:34:53 +00002109#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002110PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002111"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002112Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002113
Barry Warsaw53699e91996-12-10 23:23:01 +00002114static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002115posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002116{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002117 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002118 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002119#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002120 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002121#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002122 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002123#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002124}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002125#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002127
Guido van Rossumb6775db1994-08-01 11:34:53 +00002128#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002129PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002130"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002131Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002132
Barry Warsaw53699e91996-12-10 23:23:01 +00002133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002134posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002135{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002136 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002137 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002138#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002139 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002140#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002141 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002142#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002143 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002144 Py_INCREF(Py_None);
2145 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002146}
2147
Guido van Rossumb6775db1994-08-01 11:34:53 +00002148#endif /* HAVE_SETPGRP */
2149
Guido van Rossumad0ee831995-03-01 10:34:45 +00002150#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002151PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002152"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002153Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002154
Barry Warsaw53699e91996-12-10 23:23:01 +00002155static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002156posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002157{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002158 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002159 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002160 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002161}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002162#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002164
Fred Drake12c6e2d1999-12-14 21:25:03 +00002165#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002166PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002167"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002168Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002169
2170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002171posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002172{
2173 PyObject *result = NULL;
2174
2175 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002176 char *name;
2177 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002178
Fred Drakea30680b2000-12-06 21:24:28 +00002179 errno = 0;
2180 name = getlogin();
2181 if (name == NULL) {
2182 if (errno)
2183 posix_error();
2184 else
2185 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002186 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002187 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002188 else
2189 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002190 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002191 }
2192 return result;
2193}
2194#endif
2195
Guido van Rossumad0ee831995-03-01 10:34:45 +00002196#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002197PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002198"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002199Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002200
Barry Warsaw53699e91996-12-10 23:23:01 +00002201static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002202posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002203{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002204 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002205 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002206 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002207}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002208#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002210
Guido van Rossumad0ee831995-03-01 10:34:45 +00002211#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002212PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002213"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002214Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002215
Barry Warsaw53699e91996-12-10 23:23:01 +00002216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002217posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002218{
2219 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002220 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002221 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002222#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002223 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2224 APIRET rc;
2225 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002226 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002227
2228 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2229 APIRET rc;
2230 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002231 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002232
2233 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002234 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002235#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002236 if (kill(pid, sig) == -1)
2237 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002238#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002239 Py_INCREF(Py_None);
2240 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002241}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002242#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002243
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002244#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002245PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002246"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002247Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002248
2249static PyObject *
2250posix_killpg(PyObject *self, PyObject *args)
2251{
2252 int pgid, sig;
2253 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2254 return NULL;
2255 if (killpg(pgid, sig) == -1)
2256 return posix_error();
2257 Py_INCREF(Py_None);
2258 return Py_None;
2259}
2260#endif
2261
Guido van Rossumc0125471996-06-28 18:55:32 +00002262#ifdef HAVE_PLOCK
2263
2264#ifdef HAVE_SYS_LOCK_H
2265#include <sys/lock.h>
2266#endif
2267
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002268PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002269"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002270Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002271
Barry Warsaw53699e91996-12-10 23:23:01 +00002272static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002273posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002274{
2275 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002276 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002277 return NULL;
2278 if (plock(op) == -1)
2279 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002280 Py_INCREF(Py_None);
2281 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002282}
2283#endif
2284
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002285
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002286#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002287PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002288"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002289Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002290
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002291#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002292#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002293static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002294async_system(const char *command)
2295{
2296 char *p, errormsg[256], args[1024];
2297 RESULTCODES rcodes;
2298 APIRET rc;
2299 char *shell = getenv("COMSPEC");
2300 if (!shell)
2301 shell = "cmd";
2302
2303 strcpy(args, shell);
2304 p = &args[ strlen(args)+1 ];
2305 strcpy(p, "/c ");
2306 strcat(p, command);
2307 p += strlen(p) + 1;
2308 *p = '\0';
2309
2310 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002311 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002312 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002313 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002314 &rcodes, shell);
2315 return rc;
2316}
2317
Guido van Rossumd48f2521997-12-05 22:19:34 +00002318static FILE *
2319popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002320{
2321 HFILE rhan, whan;
2322 FILE *retfd = NULL;
2323 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2324
Guido van Rossumd48f2521997-12-05 22:19:34 +00002325 if (rc != NO_ERROR) {
2326 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002327 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002328 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002329
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002330 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2331 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002332
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002333 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2334 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002335
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002336 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2337 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002338
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002339 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002340 }
2341
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002342 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2343 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002344
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002345 if (rc == NO_ERROR)
2346 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2347
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002348 close(oldfd); /* And Close Saved STDOUT Handle */
2349 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002350
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002351 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2352 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002353
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002354 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2355 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002356
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002357 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2358 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002359
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002360 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002361 }
2362
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002363 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2364 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002365
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002366 if (rc == NO_ERROR)
2367 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2368
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002369 close(oldfd); /* And Close Saved STDIN Handle */
2370 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002371
Guido van Rossumd48f2521997-12-05 22:19:34 +00002372 } else {
2373 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002374 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002375 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002376}
2377
2378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002379posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002380{
2381 char *name;
2382 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002383 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002384 FILE *fp;
2385 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002386 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002387 return NULL;
2388 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002389 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002390 Py_END_ALLOW_THREADS
2391 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002392 return os2_error(err);
2393
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002394 f = PyFile_FromFile(fp, name, mode, fclose);
2395 if (f != NULL)
2396 PyFile_SetBufSize(f, bufsize);
2397 return f;
2398}
2399
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002400#elif defined(PYCC_GCC)
2401
2402/* standard posix version of popen() support */
2403static PyObject *
2404posix_popen(PyObject *self, PyObject *args)
2405{
2406 char *name;
2407 char *mode = "r";
2408 int bufsize = -1;
2409 FILE *fp;
2410 PyObject *f;
2411 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2412 return NULL;
2413 Py_BEGIN_ALLOW_THREADS
2414 fp = popen(name, mode);
2415 Py_END_ALLOW_THREADS
2416 if (fp == NULL)
2417 return posix_error();
2418 f = PyFile_FromFile(fp, name, mode, pclose);
2419 if (f != NULL)
2420 PyFile_SetBufSize(f, bufsize);
2421 return f;
2422}
2423
2424/* fork() under OS/2 has lots'o'warts
2425 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2426 * most of this code is a ripoff of the win32 code, but using the
2427 * capabilities of EMX's C library routines
2428 */
2429
2430/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2431#define POPEN_1 1
2432#define POPEN_2 2
2433#define POPEN_3 3
2434#define POPEN_4 4
2435
2436static PyObject *_PyPopen(char *, int, int, int);
2437static int _PyPclose(FILE *file);
2438
2439/*
2440 * Internal dictionary mapping popen* file pointers to process handles,
2441 * for use when retrieving the process exit code. See _PyPclose() below
2442 * for more information on this dictionary's use.
2443 */
2444static PyObject *_PyPopenProcs = NULL;
2445
2446/* os2emx version of popen2()
2447 *
2448 * The result of this function is a pipe (file) connected to the
2449 * process's stdin, and a pipe connected to the process's stdout.
2450 */
2451
2452static PyObject *
2453os2emx_popen2(PyObject *self, PyObject *args)
2454{
2455 PyObject *f;
2456 int tm=0;
2457
2458 char *cmdstring;
2459 char *mode = "t";
2460 int bufsize = -1;
2461 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2462 return NULL;
2463
2464 if (*mode == 't')
2465 tm = O_TEXT;
2466 else if (*mode != 'b') {
2467 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2468 return NULL;
2469 } else
2470 tm = O_BINARY;
2471
2472 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2473
2474 return f;
2475}
2476
2477/*
2478 * Variation on os2emx.popen2
2479 *
2480 * The result of this function is 3 pipes - the process's stdin,
2481 * stdout and stderr
2482 */
2483
2484static PyObject *
2485os2emx_popen3(PyObject *self, PyObject *args)
2486{
2487 PyObject *f;
2488 int tm = 0;
2489
2490 char *cmdstring;
2491 char *mode = "t";
2492 int bufsize = -1;
2493 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2494 return NULL;
2495
2496 if (*mode == 't')
2497 tm = O_TEXT;
2498 else if (*mode != 'b') {
2499 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2500 return NULL;
2501 } else
2502 tm = O_BINARY;
2503
2504 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2505
2506 return f;
2507}
2508
2509/*
2510 * Variation on os2emx.popen2
2511 *
2512 * The result of this function is 2 pipes - the processes stdin,
2513 * and stdout+stderr combined as a single pipe.
2514 */
2515
2516static PyObject *
2517os2emx_popen4(PyObject *self, PyObject *args)
2518{
2519 PyObject *f;
2520 int tm = 0;
2521
2522 char *cmdstring;
2523 char *mode = "t";
2524 int bufsize = -1;
2525 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2526 return NULL;
2527
2528 if (*mode == 't')
2529 tm = O_TEXT;
2530 else if (*mode != 'b') {
2531 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2532 return NULL;
2533 } else
2534 tm = O_BINARY;
2535
2536 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2537
2538 return f;
2539}
2540
2541/* a couple of structures for convenient handling of multiple
2542 * file handles and pipes
2543 */
2544struct file_ref
2545{
2546 int handle;
2547 int flags;
2548};
2549
2550struct pipe_ref
2551{
2552 int rd;
2553 int wr;
2554};
2555
2556/* The following code is derived from the win32 code */
2557
2558static PyObject *
2559_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2560{
2561 struct file_ref stdio[3];
2562 struct pipe_ref p_fd[3];
2563 FILE *p_s[3];
2564 int file_count, i, pipe_err, pipe_pid;
2565 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2566 PyObject *f, *p_f[3];
2567
2568 /* file modes for subsequent fdopen's on pipe handles */
2569 if (mode == O_TEXT)
2570 {
2571 rd_mode = "rt";
2572 wr_mode = "wt";
2573 }
2574 else
2575 {
2576 rd_mode = "rb";
2577 wr_mode = "wb";
2578 }
2579
2580 /* prepare shell references */
2581 if ((shell = getenv("EMXSHELL")) == NULL)
2582 if ((shell = getenv("COMSPEC")) == NULL)
2583 {
2584 errno = ENOENT;
2585 return posix_error();
2586 }
2587
2588 sh_name = _getname(shell);
2589 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2590 opt = "/c";
2591 else
2592 opt = "-c";
2593
2594 /* save current stdio fds + their flags, and set not inheritable */
2595 i = pipe_err = 0;
2596 while (pipe_err >= 0 && i < 3)
2597 {
2598 pipe_err = stdio[i].handle = dup(i);
2599 stdio[i].flags = fcntl(i, F_GETFD, 0);
2600 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2601 i++;
2602 }
2603 if (pipe_err < 0)
2604 {
2605 /* didn't get them all saved - clean up and bail out */
2606 int saved_err = errno;
2607 while (i-- > 0)
2608 {
2609 close(stdio[i].handle);
2610 }
2611 errno = saved_err;
2612 return posix_error();
2613 }
2614
2615 /* create pipe ends */
2616 file_count = 2;
2617 if (n == POPEN_3)
2618 file_count = 3;
2619 i = pipe_err = 0;
2620 while ((pipe_err == 0) && (i < file_count))
2621 pipe_err = pipe((int *)&p_fd[i++]);
2622 if (pipe_err < 0)
2623 {
2624 /* didn't get them all made - clean up and bail out */
2625 while (i-- > 0)
2626 {
2627 close(p_fd[i].wr);
2628 close(p_fd[i].rd);
2629 }
2630 errno = EPIPE;
2631 return posix_error();
2632 }
2633
2634 /* change the actual standard IO streams over temporarily,
2635 * making the retained pipe ends non-inheritable
2636 */
2637 pipe_err = 0;
2638
2639 /* - stdin */
2640 if (dup2(p_fd[0].rd, 0) == 0)
2641 {
2642 close(p_fd[0].rd);
2643 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2644 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2645 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2646 {
2647 close(p_fd[0].wr);
2648 pipe_err = -1;
2649 }
2650 }
2651 else
2652 {
2653 pipe_err = -1;
2654 }
2655
2656 /* - stdout */
2657 if (pipe_err == 0)
2658 {
2659 if (dup2(p_fd[1].wr, 1) == 1)
2660 {
2661 close(p_fd[1].wr);
2662 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2663 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2664 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2665 {
2666 close(p_fd[1].rd);
2667 pipe_err = -1;
2668 }
2669 }
2670 else
2671 {
2672 pipe_err = -1;
2673 }
2674 }
2675
2676 /* - stderr, as required */
2677 if (pipe_err == 0)
2678 switch (n)
2679 {
2680 case POPEN_3:
2681 {
2682 if (dup2(p_fd[2].wr, 2) == 2)
2683 {
2684 close(p_fd[2].wr);
2685 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2686 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2687 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2688 {
2689 close(p_fd[2].rd);
2690 pipe_err = -1;
2691 }
2692 }
2693 else
2694 {
2695 pipe_err = -1;
2696 }
2697 break;
2698 }
2699
2700 case POPEN_4:
2701 {
2702 if (dup2(1, 2) != 2)
2703 {
2704 pipe_err = -1;
2705 }
2706 break;
2707 }
2708 }
2709
2710 /* spawn the child process */
2711 if (pipe_err == 0)
2712 {
2713 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2714 if (pipe_pid == -1)
2715 {
2716 pipe_err = -1;
2717 }
2718 else
2719 {
2720 /* save the PID into the FILE structure
2721 * NOTE: this implementation doesn't actually
2722 * take advantage of this, but do it for
2723 * completeness - AIM Apr01
2724 */
2725 for (i = 0; i < file_count; i++)
2726 p_s[i]->_pid = pipe_pid;
2727 }
2728 }
2729
2730 /* reset standard IO to normal */
2731 for (i = 0; i < 3; i++)
2732 {
2733 dup2(stdio[i].handle, i);
2734 fcntl(i, F_SETFD, stdio[i].flags);
2735 close(stdio[i].handle);
2736 }
2737
2738 /* if any remnant problems, clean up and bail out */
2739 if (pipe_err < 0)
2740 {
2741 for (i = 0; i < 3; i++)
2742 {
2743 close(p_fd[i].rd);
2744 close(p_fd[i].wr);
2745 }
2746 errno = EPIPE;
2747 return posix_error_with_filename(cmdstring);
2748 }
2749
2750 /* build tuple of file objects to return */
2751 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2752 PyFile_SetBufSize(p_f[0], bufsize);
2753 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2754 PyFile_SetBufSize(p_f[1], bufsize);
2755 if (n == POPEN_3)
2756 {
2757 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2758 PyFile_SetBufSize(p_f[0], bufsize);
2759 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2760 }
2761 else
2762 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2763
2764 /*
2765 * Insert the files we've created into the process dictionary
2766 * all referencing the list with the process handle and the
2767 * initial number of files (see description below in _PyPclose).
2768 * Since if _PyPclose later tried to wait on a process when all
2769 * handles weren't closed, it could create a deadlock with the
2770 * child, we spend some energy here to try to ensure that we
2771 * either insert all file handles into the dictionary or none
2772 * at all. It's a little clumsy with the various popen modes
2773 * and variable number of files involved.
2774 */
2775 if (!_PyPopenProcs)
2776 {
2777 _PyPopenProcs = PyDict_New();
2778 }
2779
2780 if (_PyPopenProcs)
2781 {
2782 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2783 int ins_rc[3];
2784
2785 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2786 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2787
2788 procObj = PyList_New(2);
2789 pidObj = PyInt_FromLong((long) pipe_pid);
2790 intObj = PyInt_FromLong((long) file_count);
2791
2792 if (procObj && pidObj && intObj)
2793 {
2794 PyList_SetItem(procObj, 0, pidObj);
2795 PyList_SetItem(procObj, 1, intObj);
2796
2797 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2798 if (fileObj[0])
2799 {
2800 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2801 fileObj[0],
2802 procObj);
2803 }
2804 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2805 if (fileObj[1])
2806 {
2807 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2808 fileObj[1],
2809 procObj);
2810 }
2811 if (file_count >= 3)
2812 {
2813 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2814 if (fileObj[2])
2815 {
2816 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2817 fileObj[2],
2818 procObj);
2819 }
2820 }
2821
2822 if (ins_rc[0] < 0 || !fileObj[0] ||
2823 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2824 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2825 {
2826 /* Something failed - remove any dictionary
2827 * entries that did make it.
2828 */
2829 if (!ins_rc[0] && fileObj[0])
2830 {
2831 PyDict_DelItem(_PyPopenProcs,
2832 fileObj[0]);
2833 }
2834 if (!ins_rc[1] && fileObj[1])
2835 {
2836 PyDict_DelItem(_PyPopenProcs,
2837 fileObj[1]);
2838 }
2839 if (!ins_rc[2] && fileObj[2])
2840 {
2841 PyDict_DelItem(_PyPopenProcs,
2842 fileObj[2]);
2843 }
2844 }
2845 }
2846
2847 /*
2848 * Clean up our localized references for the dictionary keys
2849 * and value since PyDict_SetItem will Py_INCREF any copies
2850 * that got placed in the dictionary.
2851 */
2852 Py_XDECREF(procObj);
2853 Py_XDECREF(fileObj[0]);
2854 Py_XDECREF(fileObj[1]);
2855 Py_XDECREF(fileObj[2]);
2856 }
2857
2858 /* Child is launched. */
2859 return f;
2860}
2861
2862/*
2863 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2864 * exit code for the child process and return as a result of the close.
2865 *
2866 * This function uses the _PyPopenProcs dictionary in order to map the
2867 * input file pointer to information about the process that was
2868 * originally created by the popen* call that created the file pointer.
2869 * The dictionary uses the file pointer as a key (with one entry
2870 * inserted for each file returned by the original popen* call) and a
2871 * single list object as the value for all files from a single call.
2872 * The list object contains the Win32 process handle at [0], and a file
2873 * count at [1], which is initialized to the total number of file
2874 * handles using that list.
2875 *
2876 * This function closes whichever handle it is passed, and decrements
2877 * the file count in the dictionary for the process handle pointed to
2878 * by this file. On the last close (when the file count reaches zero),
2879 * this function will wait for the child process and then return its
2880 * exit code as the result of the close() operation. This permits the
2881 * files to be closed in any order - it is always the close() of the
2882 * final handle that will return the exit code.
2883 */
2884
2885 /* RED_FLAG 31-Aug-2000 Tim
2886 * This is always called (today!) between a pair of
2887 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2888 * macros. So the thread running this has no valid thread state, as
2889 * far as Python is concerned. However, this calls some Python API
2890 * functions that cannot be called safely without a valid thread
2891 * state, in particular PyDict_GetItem.
2892 * As a temporary hack (although it may last for years ...), we
2893 * *rely* on not having a valid thread state in this function, in
2894 * order to create our own "from scratch".
2895 * This will deadlock if _PyPclose is ever called by a thread
2896 * holding the global lock.
2897 * (The OS/2 EMX thread support appears to cover the case where the
2898 * lock is already held - AIM Apr01)
2899 */
2900
2901static int _PyPclose(FILE *file)
2902{
2903 int result;
2904 int exit_code;
2905 int pipe_pid;
2906 PyObject *procObj, *pidObj, *intObj, *fileObj;
2907 int file_count;
2908#ifdef WITH_THREAD
2909 PyInterpreterState* pInterpreterState;
2910 PyThreadState* pThreadState;
2911#endif
2912
2913 /* Close the file handle first, to ensure it can't block the
2914 * child from exiting if it's the last handle.
2915 */
2916 result = fclose(file);
2917
2918#ifdef WITH_THREAD
2919 /* Bootstrap a valid thread state into existence. */
2920 pInterpreterState = PyInterpreterState_New();
2921 if (!pInterpreterState) {
2922 /* Well, we're hosed now! We don't have a thread
2923 * state, so can't call a nice error routine, or raise
2924 * an exception. Just die.
2925 */
2926 Py_FatalError("unable to allocate interpreter state "
2927 "when closing popen object.");
2928 return -1; /* unreachable */
2929 }
2930 pThreadState = PyThreadState_New(pInterpreterState);
2931 if (!pThreadState) {
2932 Py_FatalError("unable to allocate thread state "
2933 "when closing popen object.");
2934 return -1; /* unreachable */
2935 }
2936 /* Grab the global lock. Note that this will deadlock if the
2937 * current thread already has the lock! (see RED_FLAG comments
2938 * before this function)
2939 */
2940 PyEval_RestoreThread(pThreadState);
2941#endif
2942
2943 if (_PyPopenProcs)
2944 {
2945 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2946 (procObj = PyDict_GetItem(_PyPopenProcs,
2947 fileObj)) != NULL &&
2948 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2949 (intObj = PyList_GetItem(procObj,1)) != NULL)
2950 {
2951 pipe_pid = (int) PyInt_AsLong(pidObj);
2952 file_count = (int) PyInt_AsLong(intObj);
2953
2954 if (file_count > 1)
2955 {
2956 /* Still other files referencing process */
2957 file_count--;
2958 PyList_SetItem(procObj,1,
2959 PyInt_FromLong((long) file_count));
2960 }
2961 else
2962 {
2963 /* Last file for this process */
2964 if (result != EOF &&
2965 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2966 {
2967 /* extract exit status */
2968 if (WIFEXITED(exit_code))
2969 {
2970 result = WEXITSTATUS(exit_code);
2971 }
2972 else
2973 {
2974 errno = EPIPE;
2975 result = -1;
2976 }
2977 }
2978 else
2979 {
2980 /* Indicate failure - this will cause the file object
2981 * to raise an I/O error and translate the last
2982 * error code from errno. We do have a problem with
2983 * last errors that overlap the normal errno table,
2984 * but that's a consistent problem with the file object.
2985 */
2986 result = -1;
2987 }
2988 }
2989
2990 /* Remove this file pointer from dictionary */
2991 PyDict_DelItem(_PyPopenProcs, fileObj);
2992
2993 if (PyDict_Size(_PyPopenProcs) == 0)
2994 {
2995 Py_DECREF(_PyPopenProcs);
2996 _PyPopenProcs = NULL;
2997 }
2998
2999 } /* if object retrieval ok */
3000
3001 Py_XDECREF(fileObj);
3002 } /* if _PyPopenProcs */
3003
3004#ifdef WITH_THREAD
3005 /* Tear down the thread & interpreter states.
3006 * Note that interpreter state clear & delete functions automatically
3007 * call the thread clear & delete functions, and indeed insist on
3008 * doing that themselves. The lock must be held during the clear, but
3009 * need not be held during the delete.
3010 */
3011 PyInterpreterState_Clear(pInterpreterState);
3012 PyEval_ReleaseThread(pThreadState);
3013 PyInterpreterState_Delete(pInterpreterState);
3014#endif
3015
3016 return result;
3017}
3018
3019#endif /* PYCC_??? */
3020
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003021#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003022
3023/*
3024 * Portable 'popen' replacement for Win32.
3025 *
3026 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3027 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003028 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003029 */
3030
3031#include <malloc.h>
3032#include <io.h>
3033#include <fcntl.h>
3034
3035/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3036#define POPEN_1 1
3037#define POPEN_2 2
3038#define POPEN_3 3
3039#define POPEN_4 4
3040
3041static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003042static int _PyPclose(FILE *file);
3043
3044/*
3045 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003046 * for use when retrieving the process exit code. See _PyPclose() below
3047 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003048 */
3049static PyObject *_PyPopenProcs = NULL;
3050
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003051
3052/* popen that works from a GUI.
3053 *
3054 * The result of this function is a pipe (file) connected to the
3055 * processes stdin or stdout, depending on the requested mode.
3056 */
3057
3058static PyObject *
3059posix_popen(PyObject *self, PyObject *args)
3060{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003061 PyObject *f, *s;
3062 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003063
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003064 char *cmdstring;
3065 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003066 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003067 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003068 return NULL;
3069
3070 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003071
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003072 if (*mode == 'r')
3073 tm = _O_RDONLY;
3074 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003075 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003076 return NULL;
3077 } else
3078 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003079
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003080 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003081 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003082 return NULL;
3083 }
3084
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003085 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003086 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003087 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003088 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003089 else
3090 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3091
3092 return f;
3093}
3094
3095/* Variation on win32pipe.popen
3096 *
3097 * The result of this function is a pipe (file) connected to the
3098 * process's stdin, and a pipe connected to the process's stdout.
3099 */
3100
3101static PyObject *
3102win32_popen2(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:popen2", &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, "popen2() 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, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003123 return NULL;
3124 }
3125
3126 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003127
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003128 return f;
3129}
3130
3131/*
3132 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003133 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003134 * The result of this function is 3 pipes - the process's stdin,
3135 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003136 */
3137
3138static PyObject *
3139win32_popen3(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:popen3", &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, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003154 return NULL;
3155 } else
3156 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003157
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003158 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003159 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003160 return NULL;
3161 }
3162
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003163 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003164
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003165 return f;
3166}
3167
3168/*
3169 * Variation on win32pipe.popen
3170 *
Tim Peters5aa91602002-01-30 05:46:57 +00003171 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003172 * and stdout+stderr combined as a single pipe.
3173 */
3174
3175static PyObject *
3176win32_popen4(PyObject *self, PyObject *args)
3177{
3178 PyObject *f;
3179 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003180
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003181 char *cmdstring;
3182 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003183 int bufsize = -1;
3184 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003185 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003186
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003187 if (*mode == 't')
3188 tm = _O_TEXT;
3189 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003190 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003191 return NULL;
3192 } else
3193 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003194
3195 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003196 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003197 return NULL;
3198 }
3199
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003200 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003201
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003202 return f;
3203}
3204
Mark Hammond08501372001-01-31 07:30:29 +00003205static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003206_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003207 HANDLE hStdin,
3208 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003209 HANDLE hStderr,
3210 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003211{
3212 PROCESS_INFORMATION piProcInfo;
3213 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003214 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003215 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003216 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003217 int i;
3218 int x;
3219
3220 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003221 char *comshell;
3222
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003223 s1 = (char *)_alloca(i);
3224 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3225 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003226
3227 /* Explicitly check if we are using COMMAND.COM. If we are
3228 * then use the w9xpopen hack.
3229 */
3230 comshell = s1 + x;
3231 while (comshell >= s1 && *comshell != '\\')
3232 --comshell;
3233 ++comshell;
3234
3235 if (GetVersion() < 0x80000000 &&
3236 _stricmp(comshell, "command.com") != 0) {
3237 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003238 x = i + strlen(s3) + strlen(cmdstring) + 1;
3239 s2 = (char *)_alloca(x);
3240 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003241 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003242 }
3243 else {
3244 /*
Tim Peters402d5982001-08-27 06:37:48 +00003245 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3246 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003247 */
Mark Hammond08501372001-01-31 07:30:29 +00003248 char modulepath[_MAX_PATH];
3249 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003250 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3251 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003252 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003253 x = i+1;
3254 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003255 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003256 strncat(modulepath,
3257 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003258 (sizeof(modulepath)/sizeof(modulepath[0]))
3259 -strlen(modulepath));
3260 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003261 /* Eeek - file-not-found - possibly an embedding
3262 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003263 */
Tim Peters5aa91602002-01-30 05:46:57 +00003264 strncpy(modulepath,
3265 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003266 sizeof(modulepath)/sizeof(modulepath[0]));
3267 if (modulepath[strlen(modulepath)-1] != '\\')
3268 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003269 strncat(modulepath,
3270 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003271 (sizeof(modulepath)/sizeof(modulepath[0]))
3272 -strlen(modulepath));
3273 /* No where else to look - raise an easily identifiable
3274 error, rather than leaving Windows to report
3275 "file not found" - as the user is probably blissfully
3276 unaware this shim EXE is used, and it will confuse them.
3277 (well, it confused me for a while ;-)
3278 */
3279 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003280 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003281 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003282 "for popen to work with your shell "
3283 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003284 szConsoleSpawn);
3285 return FALSE;
3286 }
3287 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003288 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003289 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003290 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003291
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003292 s2 = (char *)_alloca(x);
3293 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003294 /* To maintain correct argument passing semantics,
3295 we pass the command-line as it stands, and allow
3296 quoting to be applied. w9xpopen.exe will then
3297 use its argv vector, and re-quote the necessary
3298 args for the ultimate child process.
3299 */
Tim Peters75cdad52001-11-28 22:07:30 +00003300 PyOS_snprintf(
3301 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003302 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003303 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003304 s1,
3305 s3,
3306 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003307 /* Not passing CREATE_NEW_CONSOLE has been known to
3308 cause random failures on win9x. Specifically a
3309 dialog:
3310 "Your program accessed mem currently in use at xxx"
3311 and a hopeful warning about the stability of your
3312 system.
3313 Cost is Ctrl+C wont kill children, but anyone
3314 who cares can have a go!
3315 */
3316 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003317 }
3318 }
3319
3320 /* Could be an else here to try cmd.exe / command.com in the path
3321 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003322 else {
Tim Peters402d5982001-08-27 06:37:48 +00003323 PyErr_SetString(PyExc_RuntimeError,
3324 "Cannot locate a COMSPEC environment variable to "
3325 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003326 return FALSE;
3327 }
Tim Peters5aa91602002-01-30 05:46:57 +00003328
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003329 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3330 siStartInfo.cb = sizeof(STARTUPINFO);
3331 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3332 siStartInfo.hStdInput = hStdin;
3333 siStartInfo.hStdOutput = hStdout;
3334 siStartInfo.hStdError = hStderr;
3335 siStartInfo.wShowWindow = SW_HIDE;
3336
3337 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003338 s2,
3339 NULL,
3340 NULL,
3341 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003342 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003343 NULL,
3344 NULL,
3345 &siStartInfo,
3346 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003347 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003348 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003349
Mark Hammondb37a3732000-08-14 04:47:33 +00003350 /* Return process handle */
3351 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003352 return TRUE;
3353 }
Tim Peters402d5982001-08-27 06:37:48 +00003354 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003355 return FALSE;
3356}
3357
3358/* The following code is based off of KB: Q190351 */
3359
3360static PyObject *
3361_PyPopen(char *cmdstring, int mode, int n)
3362{
3363 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3364 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003365 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003366
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003367 SECURITY_ATTRIBUTES saAttr;
3368 BOOL fSuccess;
3369 int fd1, fd2, fd3;
3370 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003371 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003372 PyObject *f;
3373
3374 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3375 saAttr.bInheritHandle = TRUE;
3376 saAttr.lpSecurityDescriptor = NULL;
3377
3378 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3379 return win32_error("CreatePipe", NULL);
3380
3381 /* Create new output read handle and the input write handle. Set
3382 * the inheritance properties to FALSE. Otherwise, the child inherits
3383 * the these handles; resulting in non-closeable handles to the pipes
3384 * being created. */
3385 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003386 GetCurrentProcess(), &hChildStdinWrDup, 0,
3387 FALSE,
3388 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003389 if (!fSuccess)
3390 return win32_error("DuplicateHandle", NULL);
3391
3392 /* Close the inheritable version of ChildStdin
3393 that we're using. */
3394 CloseHandle(hChildStdinWr);
3395
3396 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3397 return win32_error("CreatePipe", NULL);
3398
3399 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003400 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3401 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003402 if (!fSuccess)
3403 return win32_error("DuplicateHandle", NULL);
3404
3405 /* Close the inheritable version of ChildStdout
3406 that we're using. */
3407 CloseHandle(hChildStdoutRd);
3408
3409 if (n != POPEN_4) {
3410 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3411 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003412 fSuccess = DuplicateHandle(GetCurrentProcess(),
3413 hChildStderrRd,
3414 GetCurrentProcess(),
3415 &hChildStderrRdDup, 0,
3416 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003417 if (!fSuccess)
3418 return win32_error("DuplicateHandle", NULL);
3419 /* Close the inheritable version of ChildStdErr that we're using. */
3420 CloseHandle(hChildStderrRd);
3421 }
Tim Peters5aa91602002-01-30 05:46:57 +00003422
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003423 switch (n) {
3424 case POPEN_1:
3425 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3426 case _O_WRONLY | _O_TEXT:
3427 /* Case for writing to child Stdin in text mode. */
3428 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3429 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003430 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003431 PyFile_SetBufSize(f, 0);
3432 /* We don't care about these pipes anymore, so close them. */
3433 CloseHandle(hChildStdoutRdDup);
3434 CloseHandle(hChildStderrRdDup);
3435 break;
3436
3437 case _O_RDONLY | _O_TEXT:
3438 /* Case for reading from child Stdout in text mode. */
3439 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3440 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003441 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003442 PyFile_SetBufSize(f, 0);
3443 /* We don't care about these pipes anymore, so close them. */
3444 CloseHandle(hChildStdinWrDup);
3445 CloseHandle(hChildStderrRdDup);
3446 break;
3447
3448 case _O_RDONLY | _O_BINARY:
3449 /* Case for readinig from child Stdout in binary mode. */
3450 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3451 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003452 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003453 PyFile_SetBufSize(f, 0);
3454 /* We don't care about these pipes anymore, so close them. */
3455 CloseHandle(hChildStdinWrDup);
3456 CloseHandle(hChildStderrRdDup);
3457 break;
3458
3459 case _O_WRONLY | _O_BINARY:
3460 /* Case for writing to child Stdin in binary mode. */
3461 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3462 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003463 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003464 PyFile_SetBufSize(f, 0);
3465 /* We don't care about these pipes anymore, so close them. */
3466 CloseHandle(hChildStdoutRdDup);
3467 CloseHandle(hChildStderrRdDup);
3468 break;
3469 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003470 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003471 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003472
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003473 case POPEN_2:
3474 case POPEN_4:
3475 {
3476 char *m1, *m2;
3477 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003478
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003479 if (mode && _O_TEXT) {
3480 m1 = "r";
3481 m2 = "w";
3482 } else {
3483 m1 = "rb";
3484 m2 = "wb";
3485 }
3486
3487 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3488 f1 = _fdopen(fd1, m2);
3489 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3490 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003491 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003492 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003493 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003494 PyFile_SetBufSize(p2, 0);
3495
3496 if (n != 4)
3497 CloseHandle(hChildStderrRdDup);
3498
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003499 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003500 Py_XDECREF(p1);
3501 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003502 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003503 break;
3504 }
Tim Peters5aa91602002-01-30 05:46:57 +00003505
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003506 case POPEN_3:
3507 {
3508 char *m1, *m2;
3509 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003510
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003511 if (mode && _O_TEXT) {
3512 m1 = "r";
3513 m2 = "w";
3514 } else {
3515 m1 = "rb";
3516 m2 = "wb";
3517 }
3518
3519 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3520 f1 = _fdopen(fd1, m2);
3521 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3522 f2 = _fdopen(fd2, m1);
3523 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3524 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003525 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003526 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3527 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003528 PyFile_SetBufSize(p1, 0);
3529 PyFile_SetBufSize(p2, 0);
3530 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003531 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003532 Py_XDECREF(p1);
3533 Py_XDECREF(p2);
3534 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003535 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003536 break;
3537 }
3538 }
3539
3540 if (n == POPEN_4) {
3541 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003542 hChildStdinRd,
3543 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003544 hChildStdoutWr,
3545 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003546 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003547 }
3548 else {
3549 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003550 hChildStdinRd,
3551 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003552 hChildStderrWr,
3553 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003554 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003555 }
3556
Mark Hammondb37a3732000-08-14 04:47:33 +00003557 /*
3558 * Insert the files we've created into the process dictionary
3559 * all referencing the list with the process handle and the
3560 * initial number of files (see description below in _PyPclose).
3561 * Since if _PyPclose later tried to wait on a process when all
3562 * handles weren't closed, it could create a deadlock with the
3563 * child, we spend some energy here to try to ensure that we
3564 * either insert all file handles into the dictionary or none
3565 * at all. It's a little clumsy with the various popen modes
3566 * and variable number of files involved.
3567 */
3568 if (!_PyPopenProcs) {
3569 _PyPopenProcs = PyDict_New();
3570 }
3571
3572 if (_PyPopenProcs) {
3573 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3574 int ins_rc[3];
3575
3576 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3577 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3578
3579 procObj = PyList_New(2);
3580 hProcessObj = PyLong_FromVoidPtr(hProcess);
3581 intObj = PyInt_FromLong(file_count);
3582
3583 if (procObj && hProcessObj && intObj) {
3584 PyList_SetItem(procObj,0,hProcessObj);
3585 PyList_SetItem(procObj,1,intObj);
3586
3587 fileObj[0] = PyLong_FromVoidPtr(f1);
3588 if (fileObj[0]) {
3589 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3590 fileObj[0],
3591 procObj);
3592 }
3593 if (file_count >= 2) {
3594 fileObj[1] = PyLong_FromVoidPtr(f2);
3595 if (fileObj[1]) {
3596 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3597 fileObj[1],
3598 procObj);
3599 }
3600 }
3601 if (file_count >= 3) {
3602 fileObj[2] = PyLong_FromVoidPtr(f3);
3603 if (fileObj[2]) {
3604 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3605 fileObj[2],
3606 procObj);
3607 }
3608 }
3609
3610 if (ins_rc[0] < 0 || !fileObj[0] ||
3611 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3612 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3613 /* Something failed - remove any dictionary
3614 * entries that did make it.
3615 */
3616 if (!ins_rc[0] && fileObj[0]) {
3617 PyDict_DelItem(_PyPopenProcs,
3618 fileObj[0]);
3619 }
3620 if (!ins_rc[1] && fileObj[1]) {
3621 PyDict_DelItem(_PyPopenProcs,
3622 fileObj[1]);
3623 }
3624 if (!ins_rc[2] && fileObj[2]) {
3625 PyDict_DelItem(_PyPopenProcs,
3626 fileObj[2]);
3627 }
3628 }
3629 }
Tim Peters5aa91602002-01-30 05:46:57 +00003630
Mark Hammondb37a3732000-08-14 04:47:33 +00003631 /*
3632 * Clean up our localized references for the dictionary keys
3633 * and value since PyDict_SetItem will Py_INCREF any copies
3634 * that got placed in the dictionary.
3635 */
3636 Py_XDECREF(procObj);
3637 Py_XDECREF(fileObj[0]);
3638 Py_XDECREF(fileObj[1]);
3639 Py_XDECREF(fileObj[2]);
3640 }
3641
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003642 /* Child is launched. Close the parents copy of those pipe
3643 * handles that only the child should have open. You need to
3644 * make sure that no handles to the write end of the output pipe
3645 * are maintained in this process or else the pipe will not close
3646 * when the child process exits and the ReadFile will hang. */
3647
3648 if (!CloseHandle(hChildStdinRd))
3649 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003650
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003651 if (!CloseHandle(hChildStdoutWr))
3652 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003653
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003654 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3655 return win32_error("CloseHandle", NULL);
3656
3657 return f;
3658}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003659
3660/*
3661 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3662 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003663 *
3664 * This function uses the _PyPopenProcs dictionary in order to map the
3665 * input file pointer to information about the process that was
3666 * originally created by the popen* call that created the file pointer.
3667 * The dictionary uses the file pointer as a key (with one entry
3668 * inserted for each file returned by the original popen* call) and a
3669 * single list object as the value for all files from a single call.
3670 * The list object contains the Win32 process handle at [0], and a file
3671 * count at [1], which is initialized to the total number of file
3672 * handles using that list.
3673 *
3674 * This function closes whichever handle it is passed, and decrements
3675 * the file count in the dictionary for the process handle pointed to
3676 * by this file. On the last close (when the file count reaches zero),
3677 * this function will wait for the child process and then return its
3678 * exit code as the result of the close() operation. This permits the
3679 * files to be closed in any order - it is always the close() of the
3680 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003681 */
Tim Peters736aa322000-09-01 06:51:24 +00003682
3683 /* RED_FLAG 31-Aug-2000 Tim
3684 * This is always called (today!) between a pair of
3685 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3686 * macros. So the thread running this has no valid thread state, as
3687 * far as Python is concerned. However, this calls some Python API
3688 * functions that cannot be called safely without a valid thread
3689 * state, in particular PyDict_GetItem.
3690 * As a temporary hack (although it may last for years ...), we
3691 * *rely* on not having a valid thread state in this function, in
3692 * order to create our own "from scratch".
3693 * This will deadlock if _PyPclose is ever called by a thread
3694 * holding the global lock.
3695 */
3696
Fredrik Lundh56055a42000-07-23 19:47:12 +00003697static int _PyPclose(FILE *file)
3698{
Fredrik Lundh20318932000-07-26 17:29:12 +00003699 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003700 DWORD exit_code;
3701 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003702 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3703 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003704#ifdef WITH_THREAD
3705 PyInterpreterState* pInterpreterState;
3706 PyThreadState* pThreadState;
3707#endif
3708
Fredrik Lundh20318932000-07-26 17:29:12 +00003709 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003710 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003711 */
3712 result = fclose(file);
3713
Tim Peters736aa322000-09-01 06:51:24 +00003714#ifdef WITH_THREAD
3715 /* Bootstrap a valid thread state into existence. */
3716 pInterpreterState = PyInterpreterState_New();
3717 if (!pInterpreterState) {
3718 /* Well, we're hosed now! We don't have a thread
3719 * state, so can't call a nice error routine, or raise
3720 * an exception. Just die.
3721 */
3722 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003723 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003724 return -1; /* unreachable */
3725 }
3726 pThreadState = PyThreadState_New(pInterpreterState);
3727 if (!pThreadState) {
3728 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003729 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003730 return -1; /* unreachable */
3731 }
3732 /* Grab the global lock. Note that this will deadlock if the
3733 * current thread already has the lock! (see RED_FLAG comments
3734 * before this function)
3735 */
3736 PyEval_RestoreThread(pThreadState);
3737#endif
3738
Fredrik Lundh56055a42000-07-23 19:47:12 +00003739 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003740 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3741 (procObj = PyDict_GetItem(_PyPopenProcs,
3742 fileObj)) != NULL &&
3743 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3744 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3745
3746 hProcess = PyLong_AsVoidPtr(hProcessObj);
3747 file_count = PyInt_AsLong(intObj);
3748
3749 if (file_count > 1) {
3750 /* Still other files referencing process */
3751 file_count--;
3752 PyList_SetItem(procObj,1,
3753 PyInt_FromLong(file_count));
3754 } else {
3755 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003756 if (result != EOF &&
3757 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3758 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003759 /* Possible truncation here in 16-bit environments, but
3760 * real exit codes are just the lower byte in any event.
3761 */
3762 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003763 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003764 /* Indicate failure - this will cause the file object
3765 * to raise an I/O error and translate the last Win32
3766 * error code from errno. We do have a problem with
3767 * last errors that overlap the normal errno table,
3768 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003769 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003770 if (result != EOF) {
3771 /* If the error wasn't from the fclose(), then
3772 * set errno for the file object error handling.
3773 */
3774 errno = GetLastError();
3775 }
3776 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003777 }
3778
3779 /* Free up the native handle at this point */
3780 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003781 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003782
Mark Hammondb37a3732000-08-14 04:47:33 +00003783 /* Remove this file pointer from dictionary */
3784 PyDict_DelItem(_PyPopenProcs, fileObj);
3785
3786 if (PyDict_Size(_PyPopenProcs) == 0) {
3787 Py_DECREF(_PyPopenProcs);
3788 _PyPopenProcs = NULL;
3789 }
3790
3791 } /* if object retrieval ok */
3792
3793 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003794 } /* if _PyPopenProcs */
3795
Tim Peters736aa322000-09-01 06:51:24 +00003796#ifdef WITH_THREAD
3797 /* Tear down the thread & interpreter states.
3798 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003799 * call the thread clear & delete functions, and indeed insist on
3800 * doing that themselves. The lock must be held during the clear, but
3801 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003802 */
3803 PyInterpreterState_Clear(pInterpreterState);
3804 PyEval_ReleaseThread(pThreadState);
3805 PyInterpreterState_Delete(pInterpreterState);
3806#endif
3807
Fredrik Lundh56055a42000-07-23 19:47:12 +00003808 return result;
3809}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003810
3811#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003813posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003814{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003815 char *name;
3816 char *mode = "r";
3817 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003818 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003819 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003820 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003821 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003822 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003823 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003824 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003825 if (fp == NULL)
3826 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003827 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003828 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003829 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003830 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003831}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003832
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003833#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003834#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003836
Guido van Rossumb6775db1994-08-01 11:34:53 +00003837#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003838PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003839"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003840Set the current process's user id.");
3841
Barry Warsaw53699e91996-12-10 23:23:01 +00003842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003843posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003844{
3845 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003846 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003847 return NULL;
3848 if (setuid(uid) < 0)
3849 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003850 Py_INCREF(Py_None);
3851 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003852}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003853#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003855
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003856#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003857PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003858"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003859Set the current process's effective user id.");
3860
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003861static PyObject *
3862posix_seteuid (PyObject *self, PyObject *args)
3863{
3864 int euid;
3865 if (!PyArg_ParseTuple(args, "i", &euid)) {
3866 return NULL;
3867 } else if (seteuid(euid) < 0) {
3868 return posix_error();
3869 } else {
3870 Py_INCREF(Py_None);
3871 return Py_None;
3872 }
3873}
3874#endif /* HAVE_SETEUID */
3875
3876#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003877PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003878"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003879Set the current process's effective group id.");
3880
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003881static PyObject *
3882posix_setegid (PyObject *self, PyObject *args)
3883{
3884 int egid;
3885 if (!PyArg_ParseTuple(args, "i", &egid)) {
3886 return NULL;
3887 } else if (setegid(egid) < 0) {
3888 return posix_error();
3889 } else {
3890 Py_INCREF(Py_None);
3891 return Py_None;
3892 }
3893}
3894#endif /* HAVE_SETEGID */
3895
3896#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003897PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003898"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003899Set the current process's real and effective user ids.");
3900
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003901static PyObject *
3902posix_setreuid (PyObject *self, PyObject *args)
3903{
3904 int ruid, euid;
3905 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3906 return NULL;
3907 } else if (setreuid(ruid, euid) < 0) {
3908 return posix_error();
3909 } else {
3910 Py_INCREF(Py_None);
3911 return Py_None;
3912 }
3913}
3914#endif /* HAVE_SETREUID */
3915
3916#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003917PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003918"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003919Set the current process's real and effective group ids.");
3920
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003921static PyObject *
3922posix_setregid (PyObject *self, PyObject *args)
3923{
3924 int rgid, egid;
3925 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3926 return NULL;
3927 } else if (setregid(rgid, egid) < 0) {
3928 return posix_error();
3929 } else {
3930 Py_INCREF(Py_None);
3931 return Py_None;
3932 }
3933}
3934#endif /* HAVE_SETREGID */
3935
Guido van Rossumb6775db1994-08-01 11:34:53 +00003936#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003937PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003938"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003939Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003940
Barry Warsaw53699e91996-12-10 23:23:01 +00003941static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003942posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003943{
3944 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003945 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003946 return NULL;
3947 if (setgid(gid) < 0)
3948 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003949 Py_INCREF(Py_None);
3950 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003951}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003952#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003953
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003954#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003955PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003956"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003957Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003958
3959static PyObject *
3960posix_setgroups(PyObject *self, PyObject *args)
3961{
3962 PyObject *groups;
3963 int i, len;
3964 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003965
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003966 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3967 return NULL;
3968 if (!PySequence_Check(groups)) {
3969 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3970 return NULL;
3971 }
3972 len = PySequence_Size(groups);
3973 if (len > MAX_GROUPS) {
3974 PyErr_SetString(PyExc_ValueError, "too many groups");
3975 return NULL;
3976 }
3977 for(i = 0; i < len; i++) {
3978 PyObject *elem;
3979 elem = PySequence_GetItem(groups, i);
3980 if (!elem)
3981 return NULL;
3982 if (!PyInt_Check(elem)) {
3983 PyErr_SetString(PyExc_TypeError,
3984 "groups must be integers");
3985 Py_DECREF(elem);
3986 return NULL;
3987 }
3988 /* XXX: check that value fits into gid_t. */
3989 grouplist[i] = PyInt_AsLong(elem);
3990 Py_DECREF(elem);
3991 }
3992
3993 if (setgroups(len, grouplist) < 0)
3994 return posix_error();
3995 Py_INCREF(Py_None);
3996 return Py_None;
3997}
3998#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003999
Guido van Rossumb6775db1994-08-01 11:34:53 +00004000#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004001PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004002"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004003Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004004
Barry Warsaw53699e91996-12-10 23:23:01 +00004005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004006posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004007{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004008 int pid, options;
4009#ifdef UNION_WAIT
4010 union wait status;
4011#define status_i (status.w_status)
4012#else
4013 int status;
4014#define status_i status
4015#endif
4016 status_i = 0;
4017
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004018 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004019 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004020 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004021 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004022 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004023 if (pid == -1)
4024 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004025 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004026 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004027}
4028
Tim Petersab034fa2002-02-01 11:27:43 +00004029#elif defined(HAVE_CWAIT)
4030
4031/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004032PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004033"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004034"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004035
4036static PyObject *
4037posix_waitpid(PyObject *self, PyObject *args)
4038{
4039 int pid, options;
4040 int status;
4041
4042 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4043 return NULL;
4044 Py_BEGIN_ALLOW_THREADS
4045 pid = _cwait(&status, pid, options);
4046 Py_END_ALLOW_THREADS
4047 if (pid == -1)
4048 return posix_error();
4049 else
4050 /* shift the status left a byte so this is more like the
4051 POSIX waitpid */
4052 return Py_BuildValue("ii", pid, status << 8);
4053}
4054#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004055
Guido van Rossumad0ee831995-03-01 10:34:45 +00004056#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004057PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004058"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004059Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004060
Barry Warsaw53699e91996-12-10 23:23:01 +00004061static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004062posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004063{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004064 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004065#ifdef UNION_WAIT
4066 union wait status;
4067#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004068#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004069 int status;
4070#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004071#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004072 if (!PyArg_ParseTuple(args, ":wait"))
4073 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004074 status_i = 0;
4075 Py_BEGIN_ALLOW_THREADS
4076 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004077 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004078 if (pid == -1)
4079 return posix_error();
4080 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004081 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004082#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004083}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004084#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004085
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004086
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004087PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004088"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004089Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004090
Barry Warsaw53699e91996-12-10 23:23:01 +00004091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004092posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004093{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004094#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004095 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004096#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004097 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004098#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004099}
4100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004101
Guido van Rossumb6775db1994-08-01 11:34:53 +00004102#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004103PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004104"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004105Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004106
Barry Warsaw53699e91996-12-10 23:23:01 +00004107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004108posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004109{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004110 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004111 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004112 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004113 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004114 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004115 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004116 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004117 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004118 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004119 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004120 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004121}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004122#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004124
Guido van Rossumb6775db1994-08-01 11:34:53 +00004125#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004126PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004127"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004128Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004129
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004131posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004132{
Mark Hammondef8b6542001-05-13 08:04:26 +00004133 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004134}
4135#endif /* HAVE_SYMLINK */
4136
4137
4138#ifdef HAVE_TIMES
4139#ifndef HZ
4140#define HZ 60 /* Universal constant :-) */
4141#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004142
Guido van Rossumd48f2521997-12-05 22:19:34 +00004143#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4144static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004145system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004146{
4147 ULONG value = 0;
4148
4149 Py_BEGIN_ALLOW_THREADS
4150 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4151 Py_END_ALLOW_THREADS
4152
4153 return value;
4154}
4155
4156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004157posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004158{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004159 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004160 return NULL;
4161
4162 /* Currently Only Uptime is Provided -- Others Later */
4163 return Py_BuildValue("ddddd",
4164 (double)0 /* t.tms_utime / HZ */,
4165 (double)0 /* t.tms_stime / HZ */,
4166 (double)0 /* t.tms_cutime / HZ */,
4167 (double)0 /* t.tms_cstime / HZ */,
4168 (double)system_uptime() / 1000);
4169}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004170#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004172posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004173{
4174 struct tms t;
4175 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004176 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004177 return NULL;
4178 errno = 0;
4179 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004180 if (c == (clock_t) -1)
4181 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004182 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004183 (double)t.tms_utime / HZ,
4184 (double)t.tms_stime / HZ,
4185 (double)t.tms_cutime / HZ,
4186 (double)t.tms_cstime / HZ,
4187 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004188}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004189#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004190#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004191
4192
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004193#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004194#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004196posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004197{
4198 FILETIME create, exit, kernel, user;
4199 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004200 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004201 return NULL;
4202 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004203 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4204 /* The fields of a FILETIME structure are the hi and lo part
4205 of a 64-bit value expressed in 100 nanosecond units.
4206 1e7 is one second in such units; 1e-7 the inverse.
4207 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4208 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004209 return Py_BuildValue(
4210 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004211 (double)(kernel.dwHighDateTime*429.4967296 +
4212 kernel.dwLowDateTime*1e-7),
4213 (double)(user.dwHighDateTime*429.4967296 +
4214 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004215 (double)0,
4216 (double)0,
4217 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004218}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004219#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004220
4221#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004222PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004223"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004224Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004225#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004227
Guido van Rossumb6775db1994-08-01 11:34:53 +00004228#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004229PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004230"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004231Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004232
Barry Warsaw53699e91996-12-10 23:23:01 +00004233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004234posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004235{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004236 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004237 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004238 if (setsid() < 0)
4239 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004240 Py_INCREF(Py_None);
4241 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004242}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004243#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004244
Guido van Rossumb6775db1994-08-01 11:34:53 +00004245#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004246PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004247"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004248Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004249
Barry Warsaw53699e91996-12-10 23:23:01 +00004250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004251posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004252{
4253 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004254 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004255 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004256 if (setpgid(pid, pgrp) < 0)
4257 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004258 Py_INCREF(Py_None);
4259 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004260}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004261#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004262
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004263
Guido van Rossumb6775db1994-08-01 11:34:53 +00004264#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004265PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004266"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004267Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004268
Barry Warsaw53699e91996-12-10 23:23:01 +00004269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004270posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004271{
4272 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004273 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004274 return NULL;
4275 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004276 if (pgid < 0)
4277 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004278 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004279}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004280#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004281
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004282
Guido van Rossumb6775db1994-08-01 11:34:53 +00004283#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004284PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004285"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004286Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004287
Barry Warsaw53699e91996-12-10 23:23:01 +00004288static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004289posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004290{
4291 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004292 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004293 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004294 if (tcsetpgrp(fd, pgid) < 0)
4295 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004296 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004297 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004298}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004299#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004300
Guido van Rossum687dd131993-05-17 08:34:16 +00004301/* Functions acting on file descriptors */
4302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004303PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004304"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004305Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004306
Barry Warsaw53699e91996-12-10 23:23:01 +00004307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004308posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004309{
Mark Hammondef8b6542001-05-13 08:04:26 +00004310 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004311 int flag;
4312 int mode = 0777;
4313 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004314 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004315 Py_FileSystemDefaultEncoding, &file,
4316 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004317 return NULL;
4318
Barry Warsaw53699e91996-12-10 23:23:01 +00004319 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004320 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004321 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004322 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004323 return posix_error_with_allocated_filename(file);
4324 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004325 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004326}
4327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004329PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004330"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004331Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004332
Barry Warsaw53699e91996-12-10 23:23:01 +00004333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004334posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004335{
4336 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004337 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004338 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004339 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004340 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004341 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004342 if (res < 0)
4343 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004344 Py_INCREF(Py_None);
4345 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004346}
4347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004349PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004350"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004351Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004352
Barry Warsaw53699e91996-12-10 23:23:01 +00004353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004354posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004355{
4356 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004357 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004358 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004359 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004360 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004361 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004362 if (fd < 0)
4363 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004364 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004365}
4366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004368PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004369"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004370Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004371
Barry Warsaw53699e91996-12-10 23:23:01 +00004372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004373posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004374{
4375 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004376 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004377 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004378 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004379 res = dup2(fd, fd2);
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();
Barry Warsaw53699e91996-12-10 23:23:01 +00004383 Py_INCREF(Py_None);
4384 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004385}
4386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004387
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004388PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004389"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004390Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004391
Barry Warsaw53699e91996-12-10 23:23:01 +00004392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004393posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004394{
4395 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004396#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004397 LONG_LONG pos, res;
4398#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004399 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004400#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004401 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004402 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004403 return NULL;
4404#ifdef SEEK_SET
4405 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4406 switch (how) {
4407 case 0: how = SEEK_SET; break;
4408 case 1: how = SEEK_CUR; break;
4409 case 2: how = SEEK_END; break;
4410 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004411#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004412
4413#if !defined(HAVE_LARGEFILE_SUPPORT)
4414 pos = PyInt_AsLong(posobj);
4415#else
4416 pos = PyLong_Check(posobj) ?
4417 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4418#endif
4419 if (PyErr_Occurred())
4420 return NULL;
4421
Barry Warsaw53699e91996-12-10 23:23:01 +00004422 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004423#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004424 res = _lseeki64(fd, pos, how);
4425#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004426 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004427#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004428 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004429 if (res < 0)
4430 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004431
4432#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004433 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004434#else
4435 return PyLong_FromLongLong(res);
4436#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004437}
4438
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004439
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004440PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004441"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004443
Barry Warsaw53699e91996-12-10 23:23:01 +00004444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004445posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004446{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004447 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004448 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004449 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004450 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004451 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004452 if (buffer == NULL)
4453 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004454 Py_BEGIN_ALLOW_THREADS
4455 n = read(fd, PyString_AsString(buffer), size);
4456 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004457 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004458 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004459 return posix_error();
4460 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004461 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004462 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004463 return buffer;
4464}
4465
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004467PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004468"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004469Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004470
Barry Warsaw53699e91996-12-10 23:23:01 +00004471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004472posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004473{
4474 int fd, size;
4475 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004476 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004477 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004478 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004479 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004480 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004481 if (size < 0)
4482 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004483 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004484}
4485
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004486
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004487PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004488"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004489Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004490
Barry Warsaw53699e91996-12-10 23:23:01 +00004491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004492posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004493{
4494 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004495 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004496 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004497 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004498 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004499 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004500 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004501 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004502 if (res != 0)
4503 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004504
Fred Drake699f3522000-06-29 21:12:41 +00004505 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004506}
4507
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004508
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004509PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004510"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004511Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004512
Barry Warsaw53699e91996-12-10 23:23:01 +00004513static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004514posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004515{
Guido van Rossum687dd131993-05-17 08:34:16 +00004516 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004517 char *mode = "r";
4518 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004519 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004520 PyObject *f;
4521 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004522 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004523
Barry Warsaw53699e91996-12-10 23:23:01 +00004524 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004525 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004526 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004527 if (fp == NULL)
4528 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004529 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004530 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004531 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004532 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004533}
4534
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004535PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004536"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004537Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004538connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004539
4540static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004541posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004542{
4543 int fd;
4544 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4545 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004546 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004547}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004548
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004549#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004550PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004551"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004552Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004553
Barry Warsaw53699e91996-12-10 23:23:01 +00004554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004555posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004556{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004557#if defined(PYOS_OS2)
4558 HFILE read, write;
4559 APIRET rc;
4560
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004561 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004562 return NULL;
4563
4564 Py_BEGIN_ALLOW_THREADS
4565 rc = DosCreatePipe( &read, &write, 4096);
4566 Py_END_ALLOW_THREADS
4567 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004568 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004569
4570 return Py_BuildValue("(ii)", read, write);
4571#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004572#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004573 int fds[2];
4574 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004575 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004576 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004577 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004578 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004579 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004580 if (res != 0)
4581 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004582 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004583#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004584 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004585 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004586 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004587 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004588 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004589 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004590 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004591 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004592 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004593 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004594 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4595 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004596 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004597#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004598#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004599}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004600#endif /* HAVE_PIPE */
4601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004602
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004603#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004604PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004605"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004606Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004607
Barry Warsaw53699e91996-12-10 23:23:01 +00004608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004609posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004610{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004611 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004612 int mode = 0666;
4613 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004614 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004615 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004616 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004617 res = mkfifo(filename, mode);
4618 Py_END_ALLOW_THREADS
4619 if (res < 0)
4620 return posix_error();
4621 Py_INCREF(Py_None);
4622 return Py_None;
4623}
4624#endif
4625
4626
Neal Norwitz11690112002-07-30 01:08:28 +00004627#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004628PyDoc_STRVAR(posix_mknod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004629"mknod(filename, [, mode=0600, major, minor])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004630Create a filesystem node (file, device special file or named pipe)\n\
4631named filename. mode specifies both the permissions to use and the\n\
4632type of node to be created, being combined (bitwise OR) with one of\n\
4633S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4634major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004635they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004636
4637
4638static PyObject *
4639posix_mknod(PyObject *self, PyObject *args)
4640{
4641 char *filename;
4642 int mode = 0600;
4643 int major = 0;
4644 int minor = 0;
4645 int res;
4646 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4647 &mode, &major, &minor))
4648 return NULL;
4649 Py_BEGIN_ALLOW_THREADS
4650 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004651 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004652 if (res < 0)
4653 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004654 Py_INCREF(Py_None);
4655 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004656}
4657#endif
4658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004659
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004660#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004661PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004662"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004663Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004664
Barry Warsaw53699e91996-12-10 23:23:01 +00004665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004666posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004667{
4668 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004669 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004670 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004671 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004672
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004673 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004674 return NULL;
4675
4676#if !defined(HAVE_LARGEFILE_SUPPORT)
4677 length = PyInt_AsLong(lenobj);
4678#else
4679 length = PyLong_Check(lenobj) ?
4680 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4681#endif
4682 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004683 return NULL;
4684
Barry Warsaw53699e91996-12-10 23:23:01 +00004685 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004686 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004687 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004688 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004689 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004690 return NULL;
4691 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004692 Py_INCREF(Py_None);
4693 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004694}
4695#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004696
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004697#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004698PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004699"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004700Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004701
Fred Drake762e2061999-08-26 17:23:54 +00004702/* Save putenv() parameters as values here, so we can collect them when they
4703 * get re-set with another call for the same key. */
4704static PyObject *posix_putenv_garbage;
4705
Tim Peters5aa91602002-01-30 05:46:57 +00004706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004707posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004708{
4709 char *s1, *s2;
4710 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004711 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004712 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004713
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004714 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004715 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004716
4717#if defined(PYOS_OS2)
4718 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4719 APIRET rc;
4720
4721 if (strlen(s2) == 0) /* If New Value is an Empty String */
4722 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4723
4724 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4725 if (rc != NO_ERROR)
4726 return os2_error(rc);
4727
4728 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4729 APIRET rc;
4730
4731 if (strlen(s2) == 0) /* If New Value is an Empty String */
4732 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4733
4734 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4735 if (rc != NO_ERROR)
4736 return os2_error(rc);
4737 } else {
4738#endif
4739
Fred Drake762e2061999-08-26 17:23:54 +00004740 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004741 len = strlen(s1) + strlen(s2) + 2;
4742 /* len includes space for a trailing \0; the size arg to
4743 PyString_FromStringAndSize does not count that */
4744 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004745 if (newstr == NULL)
4746 return PyErr_NoMemory();
4747 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004748 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004749 if (putenv(new)) {
4750 posix_error();
4751 return NULL;
4752 }
Fred Drake762e2061999-08-26 17:23:54 +00004753 /* Install the first arg and newstr in posix_putenv_garbage;
4754 * this will cause previous value to be collected. This has to
4755 * happen after the real putenv() call because the old value
4756 * was still accessible until then. */
4757 if (PyDict_SetItem(posix_putenv_garbage,
4758 PyTuple_GET_ITEM(args, 0), newstr)) {
4759 /* really not much we can do; just leak */
4760 PyErr_Clear();
4761 }
4762 else {
4763 Py_DECREF(newstr);
4764 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004765
4766#if defined(PYOS_OS2)
4767 }
4768#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004769 Py_INCREF(Py_None);
4770 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004771}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004772#endif /* putenv */
4773
Guido van Rossumc524d952001-10-19 01:31:59 +00004774#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004775PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004776"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004777Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00004778
4779static PyObject *
4780posix_unsetenv(PyObject *self, PyObject *args)
4781{
4782 char *s1;
4783
4784 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4785 return NULL;
4786
4787 unsetenv(s1);
4788
4789 /* Remove the key from posix_putenv_garbage;
4790 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004791 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004792 * old value was still accessible until then.
4793 */
4794 if (PyDict_DelItem(posix_putenv_garbage,
4795 PyTuple_GET_ITEM(args, 0))) {
4796 /* really not much we can do; just leak */
4797 PyErr_Clear();
4798 }
4799
4800 Py_INCREF(Py_None);
4801 return Py_None;
4802}
4803#endif /* unsetenv */
4804
Guido van Rossumb6a47161997-09-15 22:54:34 +00004805#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004806PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004807"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004808Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004809
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004810static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004811posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004812{
4813 int code;
4814 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004815 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004816 return NULL;
4817 message = strerror(code);
4818 if (message == NULL) {
4819 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004820 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004821 return NULL;
4822 }
4823 return PyString_FromString(message);
4824}
4825#endif /* strerror */
4826
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004827
Guido van Rossumc9641791998-08-04 15:26:23 +00004828#ifdef HAVE_SYS_WAIT_H
4829
Fred Drake106c1a02002-04-23 15:58:02 +00004830#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004831PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004832"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004833Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00004834
4835static PyObject *
4836posix_WCOREDUMP(PyObject *self, PyObject *args)
4837{
4838#ifdef UNION_WAIT
4839 union wait status;
4840#define status_i (status.w_status)
4841#else
4842 int status;
4843#define status_i status
4844#endif
4845 status_i = 0;
4846
4847 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4848 {
4849 return NULL;
4850 }
4851
4852 return PyBool_FromLong(WCOREDUMP(status));
4853#undef status_i
4854}
4855#endif /* WCOREDUMP */
4856
4857#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004858PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004859"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004860Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004861job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00004862
4863static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004864posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004865{
4866#ifdef UNION_WAIT
4867 union wait status;
4868#define status_i (status.w_status)
4869#else
4870 int status;
4871#define status_i status
4872#endif
4873 status_i = 0;
4874
4875 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4876 {
4877 return NULL;
4878 }
4879
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004880 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004881#undef status_i
4882}
4883#endif /* WIFCONTINUED */
4884
Guido van Rossumc9641791998-08-04 15:26:23 +00004885#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004886PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004887"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004888Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004889
4890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004891posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004892{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004893#ifdef UNION_WAIT
4894 union wait status;
4895#define status_i (status.w_status)
4896#else
4897 int status;
4898#define status_i status
4899#endif
4900 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004901
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004902 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004903 {
4904 return NULL;
4905 }
Tim Peters5aa91602002-01-30 05:46:57 +00004906
Fred Drake106c1a02002-04-23 15:58:02 +00004907 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004908#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004909}
4910#endif /* WIFSTOPPED */
4911
4912#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004913PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004914"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004915Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004916
4917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004918posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004919{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004920#ifdef UNION_WAIT
4921 union wait status;
4922#define status_i (status.w_status)
4923#else
4924 int status;
4925#define status_i status
4926#endif
4927 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004928
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004929 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004930 {
4931 return NULL;
4932 }
Tim Peters5aa91602002-01-30 05:46:57 +00004933
Fred Drake106c1a02002-04-23 15:58:02 +00004934 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004935#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004936}
4937#endif /* WIFSIGNALED */
4938
4939#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004940PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004941"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004942Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004943system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004944
4945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004946posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004947{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004948#ifdef UNION_WAIT
4949 union wait status;
4950#define status_i (status.w_status)
4951#else
4952 int status;
4953#define status_i status
4954#endif
4955 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004956
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004957 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004958 {
4959 return NULL;
4960 }
Tim Peters5aa91602002-01-30 05:46:57 +00004961
Fred Drake106c1a02002-04-23 15:58:02 +00004962 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004963#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004964}
4965#endif /* WIFEXITED */
4966
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004967#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004968PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004969"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004970Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004971
4972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004973posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004974{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004975#ifdef UNION_WAIT
4976 union wait status;
4977#define status_i (status.w_status)
4978#else
4979 int status;
4980#define status_i status
4981#endif
4982 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004983
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004984 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004985 {
4986 return NULL;
4987 }
Tim Peters5aa91602002-01-30 05:46:57 +00004988
Guido van Rossumc9641791998-08-04 15:26:23 +00004989 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004990#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004991}
4992#endif /* WEXITSTATUS */
4993
4994#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004995PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004996"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004997Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004998value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004999
5000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005001posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005002{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005003#ifdef UNION_WAIT
5004 union wait status;
5005#define status_i (status.w_status)
5006#else
5007 int status;
5008#define status_i status
5009#endif
5010 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005011
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005012 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005013 {
5014 return NULL;
5015 }
Tim Peters5aa91602002-01-30 05:46:57 +00005016
Guido van Rossumc9641791998-08-04 15:26:23 +00005017 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005018#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005019}
5020#endif /* WTERMSIG */
5021
5022#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005023PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005024"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005025Return the signal that stopped the process that provided\n\
5026the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005027
5028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005029posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005030{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005031#ifdef UNION_WAIT
5032 union wait status;
5033#define status_i (status.w_status)
5034#else
5035 int status;
5036#define status_i status
5037#endif
5038 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005039
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005040 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005041 {
5042 return NULL;
5043 }
Tim Peters5aa91602002-01-30 05:46:57 +00005044
Guido van Rossumc9641791998-08-04 15:26:23 +00005045 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005046#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005047}
5048#endif /* WSTOPSIG */
5049
5050#endif /* HAVE_SYS_WAIT_H */
5051
5052
Guido van Rossum94f6f721999-01-06 18:42:14 +00005053#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005054#ifdef _SCO_DS
5055/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5056 needed definitions in sys/statvfs.h */
5057#define _SVID3
5058#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005059#include <sys/statvfs.h>
5060
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005061static PyObject*
5062_pystatvfs_fromstructstatvfs(struct statvfs st) {
5063 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5064 if (v == NULL)
5065 return NULL;
5066
5067#if !defined(HAVE_LARGEFILE_SUPPORT)
5068 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5069 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5070 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5071 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5072 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5073 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5074 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5075 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5076 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5077 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5078#else
5079 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5080 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005081 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005082 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005083 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005084 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5085 PyStructSequence_SET_ITEM(v, 4,
5086 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005087 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005088 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005089 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005090 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005091 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005092 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5093 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5094 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5095#endif
5096
5097 return v;
5098}
5099
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005100PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005101"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005102Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005103
5104static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005105posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005106{
5107 int fd, res;
5108 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005109
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005110 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005111 return NULL;
5112 Py_BEGIN_ALLOW_THREADS
5113 res = fstatvfs(fd, &st);
5114 Py_END_ALLOW_THREADS
5115 if (res != 0)
5116 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005117
5118 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005119}
5120#endif /* HAVE_FSTATVFS */
5121
5122
5123#if defined(HAVE_STATVFS)
5124#include <sys/statvfs.h>
5125
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005126PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005127"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005128Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005129
5130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005131posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005132{
5133 char *path;
5134 int res;
5135 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005136 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005137 return NULL;
5138 Py_BEGIN_ALLOW_THREADS
5139 res = statvfs(path, &st);
5140 Py_END_ALLOW_THREADS
5141 if (res != 0)
5142 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005143
5144 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005145}
5146#endif /* HAVE_STATVFS */
5147
5148
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005149#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005150PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005151"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005152Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005153The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005154or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005155
5156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005157posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005158{
5159 PyObject *result = NULL;
5160 char *dir = NULL;
5161 char *pfx = NULL;
5162 char *name;
5163
5164 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5165 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005166
5167 if (PyErr_Warn(PyExc_RuntimeWarning,
5168 "tempnam is a potential security risk to your program") < 0)
5169 return NULL;
5170
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005171#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005172 name = _tempnam(dir, pfx);
5173#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005174 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005175#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005176 if (name == NULL)
5177 return PyErr_NoMemory();
5178 result = PyString_FromString(name);
5179 free(name);
5180 return result;
5181}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005182#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005183
5184
5185#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005186PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005187"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005188Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005189
5190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005191posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005192{
5193 FILE *fp;
5194
5195 if (!PyArg_ParseTuple(args, ":tmpfile"))
5196 return NULL;
5197 fp = tmpfile();
5198 if (fp == NULL)
5199 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005200 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005201}
5202#endif
5203
5204
5205#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005206PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005207"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005208Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005209
5210static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005211posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005212{
5213 char buffer[L_tmpnam];
5214 char *name;
5215
5216 if (!PyArg_ParseTuple(args, ":tmpnam"))
5217 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005218
5219 if (PyErr_Warn(PyExc_RuntimeWarning,
5220 "tmpnam is a potential security risk to your program") < 0)
5221 return NULL;
5222
Greg Wardb48bc172000-03-01 21:51:56 +00005223#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005224 name = tmpnam_r(buffer);
5225#else
5226 name = tmpnam(buffer);
5227#endif
5228 if (name == NULL) {
5229 PyErr_SetObject(PyExc_OSError,
5230 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005231#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005232 "unexpected NULL from tmpnam_r"
5233#else
5234 "unexpected NULL from tmpnam"
5235#endif
5236 ));
5237 return NULL;
5238 }
5239 return PyString_FromString(buffer);
5240}
5241#endif
5242
5243
Fred Drakec9680921999-12-13 16:37:25 +00005244/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5245 * It maps strings representing configuration variable names to
5246 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005247 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005248 * rarely-used constants. There are three separate tables that use
5249 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005250 *
5251 * This code is always included, even if none of the interfaces that
5252 * need it are included. The #if hackery needed to avoid it would be
5253 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005254 */
5255struct constdef {
5256 char *name;
5257 long value;
5258};
5259
Fred Drake12c6e2d1999-12-14 21:25:03 +00005260static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005261conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5262 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005263{
5264 if (PyInt_Check(arg)) {
5265 *valuep = PyInt_AS_LONG(arg);
5266 return 1;
5267 }
5268 if (PyString_Check(arg)) {
5269 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005270 size_t lo = 0;
5271 size_t mid;
5272 size_t hi = tablesize;
5273 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005274 char *confname = PyString_AS_STRING(arg);
5275 while (lo < hi) {
5276 mid = (lo + hi) / 2;
5277 cmp = strcmp(confname, table[mid].name);
5278 if (cmp < 0)
5279 hi = mid;
5280 else if (cmp > 0)
5281 lo = mid + 1;
5282 else {
5283 *valuep = table[mid].value;
5284 return 1;
5285 }
5286 }
5287 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5288 }
5289 else
5290 PyErr_SetString(PyExc_TypeError,
5291 "configuration names must be strings or integers");
5292 return 0;
5293}
5294
5295
5296#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5297static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005298#ifdef _PC_ABI_AIO_XFER_MAX
5299 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5300#endif
5301#ifdef _PC_ABI_ASYNC_IO
5302 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5303#endif
Fred Drakec9680921999-12-13 16:37:25 +00005304#ifdef _PC_ASYNC_IO
5305 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5306#endif
5307#ifdef _PC_CHOWN_RESTRICTED
5308 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5309#endif
5310#ifdef _PC_FILESIZEBITS
5311 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5312#endif
5313#ifdef _PC_LAST
5314 {"PC_LAST", _PC_LAST},
5315#endif
5316#ifdef _PC_LINK_MAX
5317 {"PC_LINK_MAX", _PC_LINK_MAX},
5318#endif
5319#ifdef _PC_MAX_CANON
5320 {"PC_MAX_CANON", _PC_MAX_CANON},
5321#endif
5322#ifdef _PC_MAX_INPUT
5323 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5324#endif
5325#ifdef _PC_NAME_MAX
5326 {"PC_NAME_MAX", _PC_NAME_MAX},
5327#endif
5328#ifdef _PC_NO_TRUNC
5329 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5330#endif
5331#ifdef _PC_PATH_MAX
5332 {"PC_PATH_MAX", _PC_PATH_MAX},
5333#endif
5334#ifdef _PC_PIPE_BUF
5335 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5336#endif
5337#ifdef _PC_PRIO_IO
5338 {"PC_PRIO_IO", _PC_PRIO_IO},
5339#endif
5340#ifdef _PC_SOCK_MAXBUF
5341 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5342#endif
5343#ifdef _PC_SYNC_IO
5344 {"PC_SYNC_IO", _PC_SYNC_IO},
5345#endif
5346#ifdef _PC_VDISABLE
5347 {"PC_VDISABLE", _PC_VDISABLE},
5348#endif
5349};
5350
Fred Drakec9680921999-12-13 16:37:25 +00005351static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005352conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005353{
5354 return conv_confname(arg, valuep, posix_constants_pathconf,
5355 sizeof(posix_constants_pathconf)
5356 / sizeof(struct constdef));
5357}
5358#endif
5359
5360#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005361PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005362"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005363Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005364If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005365
5366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005367posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005368{
5369 PyObject *result = NULL;
5370 int name, fd;
5371
Fred Drake12c6e2d1999-12-14 21:25:03 +00005372 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5373 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005374 long limit;
5375
5376 errno = 0;
5377 limit = fpathconf(fd, name);
5378 if (limit == -1 && errno != 0)
5379 posix_error();
5380 else
5381 result = PyInt_FromLong(limit);
5382 }
5383 return result;
5384}
5385#endif
5386
5387
5388#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005389PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005390"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005391Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005392If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005393
5394static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005395posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005396{
5397 PyObject *result = NULL;
5398 int name;
5399 char *path;
5400
5401 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5402 conv_path_confname, &name)) {
5403 long limit;
5404
5405 errno = 0;
5406 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005407 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005408 if (errno == EINVAL)
5409 /* could be a path or name problem */
5410 posix_error();
5411 else
5412 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005413 }
Fred Drakec9680921999-12-13 16:37:25 +00005414 else
5415 result = PyInt_FromLong(limit);
5416 }
5417 return result;
5418}
5419#endif
5420
5421#ifdef HAVE_CONFSTR
5422static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005423#ifdef _CS_ARCHITECTURE
5424 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5425#endif
5426#ifdef _CS_HOSTNAME
5427 {"CS_HOSTNAME", _CS_HOSTNAME},
5428#endif
5429#ifdef _CS_HW_PROVIDER
5430 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5431#endif
5432#ifdef _CS_HW_SERIAL
5433 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5434#endif
5435#ifdef _CS_INITTAB_NAME
5436 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5437#endif
Fred Drakec9680921999-12-13 16:37:25 +00005438#ifdef _CS_LFS64_CFLAGS
5439 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5440#endif
5441#ifdef _CS_LFS64_LDFLAGS
5442 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5443#endif
5444#ifdef _CS_LFS64_LIBS
5445 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5446#endif
5447#ifdef _CS_LFS64_LINTFLAGS
5448 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5449#endif
5450#ifdef _CS_LFS_CFLAGS
5451 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5452#endif
5453#ifdef _CS_LFS_LDFLAGS
5454 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5455#endif
5456#ifdef _CS_LFS_LIBS
5457 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5458#endif
5459#ifdef _CS_LFS_LINTFLAGS
5460 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5461#endif
Fred Draked86ed291999-12-15 15:34:33 +00005462#ifdef _CS_MACHINE
5463 {"CS_MACHINE", _CS_MACHINE},
5464#endif
Fred Drakec9680921999-12-13 16:37:25 +00005465#ifdef _CS_PATH
5466 {"CS_PATH", _CS_PATH},
5467#endif
Fred Draked86ed291999-12-15 15:34:33 +00005468#ifdef _CS_RELEASE
5469 {"CS_RELEASE", _CS_RELEASE},
5470#endif
5471#ifdef _CS_SRPC_DOMAIN
5472 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5473#endif
5474#ifdef _CS_SYSNAME
5475 {"CS_SYSNAME", _CS_SYSNAME},
5476#endif
5477#ifdef _CS_VERSION
5478 {"CS_VERSION", _CS_VERSION},
5479#endif
Fred Drakec9680921999-12-13 16:37:25 +00005480#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5481 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5482#endif
5483#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5484 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5485#endif
5486#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5487 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5488#endif
5489#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5490 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5491#endif
5492#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5493 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5494#endif
5495#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5496 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5497#endif
5498#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5499 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5500#endif
5501#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5502 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5503#endif
5504#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5505 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5506#endif
5507#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5508 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5509#endif
5510#ifdef _CS_XBS5_LP64_OFF64_LIBS
5511 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5512#endif
5513#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5514 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5515#endif
5516#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5517 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5518#endif
5519#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5520 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5521#endif
5522#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5523 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5524#endif
5525#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5526 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5527#endif
Fred Draked86ed291999-12-15 15:34:33 +00005528#ifdef _MIPS_CS_AVAIL_PROCESSORS
5529 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5530#endif
5531#ifdef _MIPS_CS_BASE
5532 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5533#endif
5534#ifdef _MIPS_CS_HOSTID
5535 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5536#endif
5537#ifdef _MIPS_CS_HW_NAME
5538 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5539#endif
5540#ifdef _MIPS_CS_NUM_PROCESSORS
5541 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5542#endif
5543#ifdef _MIPS_CS_OSREL_MAJ
5544 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5545#endif
5546#ifdef _MIPS_CS_OSREL_MIN
5547 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5548#endif
5549#ifdef _MIPS_CS_OSREL_PATCH
5550 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5551#endif
5552#ifdef _MIPS_CS_OS_NAME
5553 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5554#endif
5555#ifdef _MIPS_CS_OS_PROVIDER
5556 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5557#endif
5558#ifdef _MIPS_CS_PROCESSORS
5559 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5560#endif
5561#ifdef _MIPS_CS_SERIAL
5562 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5563#endif
5564#ifdef _MIPS_CS_VENDOR
5565 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5566#endif
Fred Drakec9680921999-12-13 16:37:25 +00005567};
5568
5569static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005570conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005571{
5572 return conv_confname(arg, valuep, posix_constants_confstr,
5573 sizeof(posix_constants_confstr)
5574 / sizeof(struct constdef));
5575}
5576
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005577PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005578"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005579Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005580
5581static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005582posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005583{
5584 PyObject *result = NULL;
5585 int name;
5586 char buffer[64];
5587
5588 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5589 int len = confstr(name, buffer, sizeof(buffer));
5590
Fred Drakec9680921999-12-13 16:37:25 +00005591 errno = 0;
5592 if (len == 0) {
5593 if (errno != 0)
5594 posix_error();
5595 else
5596 result = PyString_FromString("");
5597 }
5598 else {
5599 if (len >= sizeof(buffer)) {
5600 result = PyString_FromStringAndSize(NULL, len);
5601 if (result != NULL)
5602 confstr(name, PyString_AS_STRING(result), len+1);
5603 }
5604 else
5605 result = PyString_FromString(buffer);
5606 }
5607 }
5608 return result;
5609}
5610#endif
5611
5612
5613#ifdef HAVE_SYSCONF
5614static struct constdef posix_constants_sysconf[] = {
5615#ifdef _SC_2_CHAR_TERM
5616 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5617#endif
5618#ifdef _SC_2_C_BIND
5619 {"SC_2_C_BIND", _SC_2_C_BIND},
5620#endif
5621#ifdef _SC_2_C_DEV
5622 {"SC_2_C_DEV", _SC_2_C_DEV},
5623#endif
5624#ifdef _SC_2_C_VERSION
5625 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5626#endif
5627#ifdef _SC_2_FORT_DEV
5628 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5629#endif
5630#ifdef _SC_2_FORT_RUN
5631 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5632#endif
5633#ifdef _SC_2_LOCALEDEF
5634 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5635#endif
5636#ifdef _SC_2_SW_DEV
5637 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5638#endif
5639#ifdef _SC_2_UPE
5640 {"SC_2_UPE", _SC_2_UPE},
5641#endif
5642#ifdef _SC_2_VERSION
5643 {"SC_2_VERSION", _SC_2_VERSION},
5644#endif
Fred Draked86ed291999-12-15 15:34:33 +00005645#ifdef _SC_ABI_ASYNCHRONOUS_IO
5646 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5647#endif
5648#ifdef _SC_ACL
5649 {"SC_ACL", _SC_ACL},
5650#endif
Fred Drakec9680921999-12-13 16:37:25 +00005651#ifdef _SC_AIO_LISTIO_MAX
5652 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5653#endif
Fred Drakec9680921999-12-13 16:37:25 +00005654#ifdef _SC_AIO_MAX
5655 {"SC_AIO_MAX", _SC_AIO_MAX},
5656#endif
5657#ifdef _SC_AIO_PRIO_DELTA_MAX
5658 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5659#endif
5660#ifdef _SC_ARG_MAX
5661 {"SC_ARG_MAX", _SC_ARG_MAX},
5662#endif
5663#ifdef _SC_ASYNCHRONOUS_IO
5664 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5665#endif
5666#ifdef _SC_ATEXIT_MAX
5667 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5668#endif
Fred Draked86ed291999-12-15 15:34:33 +00005669#ifdef _SC_AUDIT
5670 {"SC_AUDIT", _SC_AUDIT},
5671#endif
Fred Drakec9680921999-12-13 16:37:25 +00005672#ifdef _SC_AVPHYS_PAGES
5673 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5674#endif
5675#ifdef _SC_BC_BASE_MAX
5676 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5677#endif
5678#ifdef _SC_BC_DIM_MAX
5679 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5680#endif
5681#ifdef _SC_BC_SCALE_MAX
5682 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5683#endif
5684#ifdef _SC_BC_STRING_MAX
5685 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5686#endif
Fred Draked86ed291999-12-15 15:34:33 +00005687#ifdef _SC_CAP
5688 {"SC_CAP", _SC_CAP},
5689#endif
Fred Drakec9680921999-12-13 16:37:25 +00005690#ifdef _SC_CHARCLASS_NAME_MAX
5691 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5692#endif
5693#ifdef _SC_CHAR_BIT
5694 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5695#endif
5696#ifdef _SC_CHAR_MAX
5697 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5698#endif
5699#ifdef _SC_CHAR_MIN
5700 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5701#endif
5702#ifdef _SC_CHILD_MAX
5703 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5704#endif
5705#ifdef _SC_CLK_TCK
5706 {"SC_CLK_TCK", _SC_CLK_TCK},
5707#endif
5708#ifdef _SC_COHER_BLKSZ
5709 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5710#endif
5711#ifdef _SC_COLL_WEIGHTS_MAX
5712 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5713#endif
5714#ifdef _SC_DCACHE_ASSOC
5715 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5716#endif
5717#ifdef _SC_DCACHE_BLKSZ
5718 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5719#endif
5720#ifdef _SC_DCACHE_LINESZ
5721 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5722#endif
5723#ifdef _SC_DCACHE_SZ
5724 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5725#endif
5726#ifdef _SC_DCACHE_TBLKSZ
5727 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5728#endif
5729#ifdef _SC_DELAYTIMER_MAX
5730 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5731#endif
5732#ifdef _SC_EQUIV_CLASS_MAX
5733 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5734#endif
5735#ifdef _SC_EXPR_NEST_MAX
5736 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5737#endif
5738#ifdef _SC_FSYNC
5739 {"SC_FSYNC", _SC_FSYNC},
5740#endif
5741#ifdef _SC_GETGR_R_SIZE_MAX
5742 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5743#endif
5744#ifdef _SC_GETPW_R_SIZE_MAX
5745 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5746#endif
5747#ifdef _SC_ICACHE_ASSOC
5748 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5749#endif
5750#ifdef _SC_ICACHE_BLKSZ
5751 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5752#endif
5753#ifdef _SC_ICACHE_LINESZ
5754 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5755#endif
5756#ifdef _SC_ICACHE_SZ
5757 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5758#endif
Fred Draked86ed291999-12-15 15:34:33 +00005759#ifdef _SC_INF
5760 {"SC_INF", _SC_INF},
5761#endif
Fred Drakec9680921999-12-13 16:37:25 +00005762#ifdef _SC_INT_MAX
5763 {"SC_INT_MAX", _SC_INT_MAX},
5764#endif
5765#ifdef _SC_INT_MIN
5766 {"SC_INT_MIN", _SC_INT_MIN},
5767#endif
5768#ifdef _SC_IOV_MAX
5769 {"SC_IOV_MAX", _SC_IOV_MAX},
5770#endif
Fred Draked86ed291999-12-15 15:34:33 +00005771#ifdef _SC_IP_SECOPTS
5772 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5773#endif
Fred Drakec9680921999-12-13 16:37:25 +00005774#ifdef _SC_JOB_CONTROL
5775 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5776#endif
Fred Draked86ed291999-12-15 15:34:33 +00005777#ifdef _SC_KERN_POINTERS
5778 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5779#endif
5780#ifdef _SC_KERN_SIM
5781 {"SC_KERN_SIM", _SC_KERN_SIM},
5782#endif
Fred Drakec9680921999-12-13 16:37:25 +00005783#ifdef _SC_LINE_MAX
5784 {"SC_LINE_MAX", _SC_LINE_MAX},
5785#endif
5786#ifdef _SC_LOGIN_NAME_MAX
5787 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5788#endif
5789#ifdef _SC_LOGNAME_MAX
5790 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5791#endif
5792#ifdef _SC_LONG_BIT
5793 {"SC_LONG_BIT", _SC_LONG_BIT},
5794#endif
Fred Draked86ed291999-12-15 15:34:33 +00005795#ifdef _SC_MAC
5796 {"SC_MAC", _SC_MAC},
5797#endif
Fred Drakec9680921999-12-13 16:37:25 +00005798#ifdef _SC_MAPPED_FILES
5799 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5800#endif
5801#ifdef _SC_MAXPID
5802 {"SC_MAXPID", _SC_MAXPID},
5803#endif
5804#ifdef _SC_MB_LEN_MAX
5805 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5806#endif
5807#ifdef _SC_MEMLOCK
5808 {"SC_MEMLOCK", _SC_MEMLOCK},
5809#endif
5810#ifdef _SC_MEMLOCK_RANGE
5811 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5812#endif
5813#ifdef _SC_MEMORY_PROTECTION
5814 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5815#endif
5816#ifdef _SC_MESSAGE_PASSING
5817 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5818#endif
Fred Draked86ed291999-12-15 15:34:33 +00005819#ifdef _SC_MMAP_FIXED_ALIGNMENT
5820 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5821#endif
Fred Drakec9680921999-12-13 16:37:25 +00005822#ifdef _SC_MQ_OPEN_MAX
5823 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5824#endif
5825#ifdef _SC_MQ_PRIO_MAX
5826 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5827#endif
Fred Draked86ed291999-12-15 15:34:33 +00005828#ifdef _SC_NACLS_MAX
5829 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5830#endif
Fred Drakec9680921999-12-13 16:37:25 +00005831#ifdef _SC_NGROUPS_MAX
5832 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5833#endif
5834#ifdef _SC_NL_ARGMAX
5835 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5836#endif
5837#ifdef _SC_NL_LANGMAX
5838 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5839#endif
5840#ifdef _SC_NL_MSGMAX
5841 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5842#endif
5843#ifdef _SC_NL_NMAX
5844 {"SC_NL_NMAX", _SC_NL_NMAX},
5845#endif
5846#ifdef _SC_NL_SETMAX
5847 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5848#endif
5849#ifdef _SC_NL_TEXTMAX
5850 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5851#endif
5852#ifdef _SC_NPROCESSORS_CONF
5853 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5854#endif
5855#ifdef _SC_NPROCESSORS_ONLN
5856 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5857#endif
Fred Draked86ed291999-12-15 15:34:33 +00005858#ifdef _SC_NPROC_CONF
5859 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5860#endif
5861#ifdef _SC_NPROC_ONLN
5862 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5863#endif
Fred Drakec9680921999-12-13 16:37:25 +00005864#ifdef _SC_NZERO
5865 {"SC_NZERO", _SC_NZERO},
5866#endif
5867#ifdef _SC_OPEN_MAX
5868 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5869#endif
5870#ifdef _SC_PAGESIZE
5871 {"SC_PAGESIZE", _SC_PAGESIZE},
5872#endif
5873#ifdef _SC_PAGE_SIZE
5874 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5875#endif
5876#ifdef _SC_PASS_MAX
5877 {"SC_PASS_MAX", _SC_PASS_MAX},
5878#endif
5879#ifdef _SC_PHYS_PAGES
5880 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5881#endif
5882#ifdef _SC_PII
5883 {"SC_PII", _SC_PII},
5884#endif
5885#ifdef _SC_PII_INTERNET
5886 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5887#endif
5888#ifdef _SC_PII_INTERNET_DGRAM
5889 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5890#endif
5891#ifdef _SC_PII_INTERNET_STREAM
5892 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5893#endif
5894#ifdef _SC_PII_OSI
5895 {"SC_PII_OSI", _SC_PII_OSI},
5896#endif
5897#ifdef _SC_PII_OSI_CLTS
5898 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5899#endif
5900#ifdef _SC_PII_OSI_COTS
5901 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5902#endif
5903#ifdef _SC_PII_OSI_M
5904 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5905#endif
5906#ifdef _SC_PII_SOCKET
5907 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5908#endif
5909#ifdef _SC_PII_XTI
5910 {"SC_PII_XTI", _SC_PII_XTI},
5911#endif
5912#ifdef _SC_POLL
5913 {"SC_POLL", _SC_POLL},
5914#endif
5915#ifdef _SC_PRIORITIZED_IO
5916 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5917#endif
5918#ifdef _SC_PRIORITY_SCHEDULING
5919 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5920#endif
5921#ifdef _SC_REALTIME_SIGNALS
5922 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5923#endif
5924#ifdef _SC_RE_DUP_MAX
5925 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5926#endif
5927#ifdef _SC_RTSIG_MAX
5928 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5929#endif
5930#ifdef _SC_SAVED_IDS
5931 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5932#endif
5933#ifdef _SC_SCHAR_MAX
5934 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5935#endif
5936#ifdef _SC_SCHAR_MIN
5937 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5938#endif
5939#ifdef _SC_SELECT
5940 {"SC_SELECT", _SC_SELECT},
5941#endif
5942#ifdef _SC_SEMAPHORES
5943 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5944#endif
5945#ifdef _SC_SEM_NSEMS_MAX
5946 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5947#endif
5948#ifdef _SC_SEM_VALUE_MAX
5949 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5950#endif
5951#ifdef _SC_SHARED_MEMORY_OBJECTS
5952 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5953#endif
5954#ifdef _SC_SHRT_MAX
5955 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5956#endif
5957#ifdef _SC_SHRT_MIN
5958 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5959#endif
5960#ifdef _SC_SIGQUEUE_MAX
5961 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5962#endif
5963#ifdef _SC_SIGRT_MAX
5964 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5965#endif
5966#ifdef _SC_SIGRT_MIN
5967 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5968#endif
Fred Draked86ed291999-12-15 15:34:33 +00005969#ifdef _SC_SOFTPOWER
5970 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5971#endif
Fred Drakec9680921999-12-13 16:37:25 +00005972#ifdef _SC_SPLIT_CACHE
5973 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5974#endif
5975#ifdef _SC_SSIZE_MAX
5976 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5977#endif
5978#ifdef _SC_STACK_PROT
5979 {"SC_STACK_PROT", _SC_STACK_PROT},
5980#endif
5981#ifdef _SC_STREAM_MAX
5982 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5983#endif
5984#ifdef _SC_SYNCHRONIZED_IO
5985 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5986#endif
5987#ifdef _SC_THREADS
5988 {"SC_THREADS", _SC_THREADS},
5989#endif
5990#ifdef _SC_THREAD_ATTR_STACKADDR
5991 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5992#endif
5993#ifdef _SC_THREAD_ATTR_STACKSIZE
5994 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5995#endif
5996#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5997 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5998#endif
5999#ifdef _SC_THREAD_KEYS_MAX
6000 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6001#endif
6002#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6003 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6004#endif
6005#ifdef _SC_THREAD_PRIO_INHERIT
6006 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6007#endif
6008#ifdef _SC_THREAD_PRIO_PROTECT
6009 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6010#endif
6011#ifdef _SC_THREAD_PROCESS_SHARED
6012 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6013#endif
6014#ifdef _SC_THREAD_SAFE_FUNCTIONS
6015 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6016#endif
6017#ifdef _SC_THREAD_STACK_MIN
6018 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6019#endif
6020#ifdef _SC_THREAD_THREADS_MAX
6021 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6022#endif
6023#ifdef _SC_TIMERS
6024 {"SC_TIMERS", _SC_TIMERS},
6025#endif
6026#ifdef _SC_TIMER_MAX
6027 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6028#endif
6029#ifdef _SC_TTY_NAME_MAX
6030 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6031#endif
6032#ifdef _SC_TZNAME_MAX
6033 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6034#endif
6035#ifdef _SC_T_IOV_MAX
6036 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6037#endif
6038#ifdef _SC_UCHAR_MAX
6039 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6040#endif
6041#ifdef _SC_UINT_MAX
6042 {"SC_UINT_MAX", _SC_UINT_MAX},
6043#endif
6044#ifdef _SC_UIO_MAXIOV
6045 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6046#endif
6047#ifdef _SC_ULONG_MAX
6048 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6049#endif
6050#ifdef _SC_USHRT_MAX
6051 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6052#endif
6053#ifdef _SC_VERSION
6054 {"SC_VERSION", _SC_VERSION},
6055#endif
6056#ifdef _SC_WORD_BIT
6057 {"SC_WORD_BIT", _SC_WORD_BIT},
6058#endif
6059#ifdef _SC_XBS5_ILP32_OFF32
6060 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6061#endif
6062#ifdef _SC_XBS5_ILP32_OFFBIG
6063 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6064#endif
6065#ifdef _SC_XBS5_LP64_OFF64
6066 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6067#endif
6068#ifdef _SC_XBS5_LPBIG_OFFBIG
6069 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6070#endif
6071#ifdef _SC_XOPEN_CRYPT
6072 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6073#endif
6074#ifdef _SC_XOPEN_ENH_I18N
6075 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6076#endif
6077#ifdef _SC_XOPEN_LEGACY
6078 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6079#endif
6080#ifdef _SC_XOPEN_REALTIME
6081 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6082#endif
6083#ifdef _SC_XOPEN_REALTIME_THREADS
6084 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6085#endif
6086#ifdef _SC_XOPEN_SHM
6087 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6088#endif
6089#ifdef _SC_XOPEN_UNIX
6090 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6091#endif
6092#ifdef _SC_XOPEN_VERSION
6093 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6094#endif
6095#ifdef _SC_XOPEN_XCU_VERSION
6096 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6097#endif
6098#ifdef _SC_XOPEN_XPG2
6099 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6100#endif
6101#ifdef _SC_XOPEN_XPG3
6102 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6103#endif
6104#ifdef _SC_XOPEN_XPG4
6105 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6106#endif
6107};
6108
6109static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006110conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006111{
6112 return conv_confname(arg, valuep, posix_constants_sysconf,
6113 sizeof(posix_constants_sysconf)
6114 / sizeof(struct constdef));
6115}
6116
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006120
6121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006122posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006123{
6124 PyObject *result = NULL;
6125 int name;
6126
6127 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6128 int value;
6129
6130 errno = 0;
6131 value = sysconf(name);
6132 if (value == -1 && errno != 0)
6133 posix_error();
6134 else
6135 result = PyInt_FromLong(value);
6136 }
6137 return result;
6138}
6139#endif
6140
6141
Fred Drakebec628d1999-12-15 18:31:10 +00006142/* This code is used to ensure that the tables of configuration value names
6143 * are in sorted order as required by conv_confname(), and also to build the
6144 * the exported dictionaries that are used to publish information about the
6145 * names available on the host platform.
6146 *
6147 * Sorting the table at runtime ensures that the table is properly ordered
6148 * when used, even for platforms we're not able to test on. It also makes
6149 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006150 */
Fred Drakebec628d1999-12-15 18:31:10 +00006151
6152static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006153cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006154{
6155 const struct constdef *c1 =
6156 (const struct constdef *) v1;
6157 const struct constdef *c2 =
6158 (const struct constdef *) v2;
6159
6160 return strcmp(c1->name, c2->name);
6161}
6162
6163static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006164setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006165 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006166{
Fred Drakebec628d1999-12-15 18:31:10 +00006167 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006168 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006169
6170 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6171 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006172 if (d == NULL)
6173 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006174
Barry Warsaw3155db32000-04-13 15:20:40 +00006175 for (i=0; i < tablesize; ++i) {
6176 PyObject *o = PyInt_FromLong(table[i].value);
6177 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6178 Py_XDECREF(o);
6179 Py_DECREF(d);
6180 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006181 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006182 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006183 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006184 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006185}
6186
Fred Drakebec628d1999-12-15 18:31:10 +00006187/* Return -1 on failure, 0 on success. */
6188static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006189setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006190{
6191#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006192 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006193 sizeof(posix_constants_pathconf)
6194 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006195 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006196 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006197#endif
6198#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006199 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006200 sizeof(posix_constants_confstr)
6201 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006202 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006203 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006204#endif
6205#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006206 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006207 sizeof(posix_constants_sysconf)
6208 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006209 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006210 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006211#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006212 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006213}
Fred Draked86ed291999-12-15 15:34:33 +00006214
6215
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006216PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006217"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006218Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006219in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006220
6221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006222posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006223{
6224 if (!PyArg_ParseTuple(args, ":abort"))
6225 return NULL;
6226 abort();
6227 /*NOTREACHED*/
6228 Py_FatalError("abort() called from Python code didn't abort!");
6229 return NULL;
6230}
Fred Drakebec628d1999-12-15 18:31:10 +00006231
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006232#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006233PyDoc_STRVAR(win32_startfile__doc__,
6234"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006235\n\
6236This acts like double-clicking the file in Explorer, or giving the file\n\
6237name as an argument to the DOS \"start\" command: the file is opened\n\
6238with whatever application (if any) its extension is associated.\n\
6239\n\
6240startfile returns as soon as the associated application is launched.\n\
6241There is no option to wait for the application to close, and no way\n\
6242to retrieve the application's exit status.\n\
6243\n\
6244The filepath is relative to the current directory. If you want to use\n\
6245an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006247
6248static PyObject *
6249win32_startfile(PyObject *self, PyObject *args)
6250{
6251 char *filepath;
6252 HINSTANCE rc;
6253 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6254 return NULL;
6255 Py_BEGIN_ALLOW_THREADS
6256 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6257 Py_END_ALLOW_THREADS
6258 if (rc <= (HINSTANCE)32)
6259 return win32_error("startfile", filepath);
6260 Py_INCREF(Py_None);
6261 return Py_None;
6262}
6263#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006264
6265static PyMethodDef posix_methods[] = {
6266 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6267#ifdef HAVE_TTYNAME
6268 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6269#endif
6270 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6271 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006272#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006273 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006274#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006275#ifdef HAVE_LCHOWN
6276 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6277#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006278#ifdef HAVE_CHROOT
6279 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6280#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006281#ifdef HAVE_CTERMID
6282 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6283#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006284#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006285 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006286#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006287#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006288 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006289#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006290 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6291 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6292 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006293#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006294 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006295#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006296#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006297 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006298#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006299 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6300 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6301 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006302#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006303 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006304#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006305#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006306 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006307#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006308 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006309#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006310 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006311#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006312 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6313 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6314 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006315#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006316 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006317#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006318 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006319#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006320 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6321 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006322#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006323#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006324 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6325 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006326#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006327#ifdef HAVE_FORK1
6328 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6329#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006330#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006331 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006332#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006333#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006334 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006335#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006336#ifdef HAVE_FORKPTY
6337 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6338#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006339#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006340 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006341#endif /* HAVE_GETEGID */
6342#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006343 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006344#endif /* HAVE_GETEUID */
6345#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006346 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006347#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006348#ifdef HAVE_GETGROUPS
6349 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6350#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006351 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006352#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006353 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006354#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006355#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006356 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006357#endif /* HAVE_GETPPID */
6358#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006359 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006360#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006361#ifdef HAVE_GETLOGIN
6362 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6363#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006364#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006366#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006367#ifdef HAVE_KILLPG
6368 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6369#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006370#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006371 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006372#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006373#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006374 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006375#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006376 {"popen2", win32_popen2, METH_VARARGS},
6377 {"popen3", win32_popen3, METH_VARARGS},
6378 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006379 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006380#else
6381#if defined(PYOS_OS2) && defined(PYCC_GCC)
6382 {"popen2", os2emx_popen2, METH_VARARGS},
6383 {"popen3", os2emx_popen3, METH_VARARGS},
6384 {"popen4", os2emx_popen4, METH_VARARGS},
6385#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006386#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006387#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006388#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006389 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006390#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006391#ifdef HAVE_SETEUID
6392 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6393#endif /* HAVE_SETEUID */
6394#ifdef HAVE_SETEGID
6395 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6396#endif /* HAVE_SETEGID */
6397#ifdef HAVE_SETREUID
6398 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6399#endif /* HAVE_SETREUID */
6400#ifdef HAVE_SETREGID
6401 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6402#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006403#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006404 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006405#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006406#ifdef HAVE_SETGROUPS
6407 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6408#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006409#ifdef HAVE_GETPGID
6410 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6411#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006412#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006413 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006414#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006415#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006416 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006417#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006418#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006419 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006420#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006421#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006422 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006423#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006424#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006425 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006426#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006427#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006428 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006429#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006430#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006431 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006432#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006433 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6434 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6435 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6436 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6437 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6438 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6439 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6440 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6441 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006442 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006443#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006444 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006445#endif
6446#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006447 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006448#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006449#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006450 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6451#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006452#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006453 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006454#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006455#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006456 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006457#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006458#ifdef HAVE_UNSETENV
6459 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6460#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006461#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006462 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006463#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006464#ifdef HAVE_FCHDIR
6465 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6466#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006467#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006468 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006469#endif
6470#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006471 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006472#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006473#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006474#ifdef WCOREDUMP
6475 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6476#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006477#ifdef WIFCONTINUED
6478 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6479#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006480#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006481 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006482#endif /* WIFSTOPPED */
6483#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006484 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006485#endif /* WIFSIGNALED */
6486#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006487 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006488#endif /* WIFEXITED */
6489#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006490 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006491#endif /* WEXITSTATUS */
6492#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006493 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006494#endif /* WTERMSIG */
6495#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006496 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006497#endif /* WSTOPSIG */
6498#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006499#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006500 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006501#endif
6502#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006503 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006504#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006505#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006506 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6507#endif
6508#ifdef HAVE_TEMPNAM
6509 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6510#endif
6511#ifdef HAVE_TMPNAM
6512 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6513#endif
Fred Drakec9680921999-12-13 16:37:25 +00006514#ifdef HAVE_CONFSTR
6515 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6516#endif
6517#ifdef HAVE_SYSCONF
6518 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6519#endif
6520#ifdef HAVE_FPATHCONF
6521 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6522#endif
6523#ifdef HAVE_PATHCONF
6524 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6525#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006526 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006527#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006528 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6529#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006530 {NULL, NULL} /* Sentinel */
6531};
6532
6533
Barry Warsaw4a342091996-12-19 23:50:02 +00006534static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006535ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006536{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006537 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006538}
6539
Guido van Rossumd48f2521997-12-05 22:19:34 +00006540#if defined(PYOS_OS2)
6541/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006542static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006543{
6544 APIRET rc;
6545 ULONG values[QSV_MAX+1];
6546 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006547 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006548
6549 Py_BEGIN_ALLOW_THREADS
6550 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6551 Py_END_ALLOW_THREADS
6552
6553 if (rc != NO_ERROR) {
6554 os2_error(rc);
6555 return -1;
6556 }
6557
Fred Drake4d1e64b2002-04-15 19:40:07 +00006558 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6559 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6560 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6561 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6562 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6563 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6564 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006565
6566 switch (values[QSV_VERSION_MINOR]) {
6567 case 0: ver = "2.00"; break;
6568 case 10: ver = "2.10"; break;
6569 case 11: ver = "2.11"; break;
6570 case 30: ver = "3.00"; break;
6571 case 40: ver = "4.00"; break;
6572 case 50: ver = "5.00"; break;
6573 default:
Tim Peters885d4572001-11-28 20:27:42 +00006574 PyOS_snprintf(tmp, sizeof(tmp),
6575 "%d-%d", values[QSV_VERSION_MAJOR],
6576 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006577 ver = &tmp[0];
6578 }
6579
6580 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006581 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006582 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006583
6584 /* Add Indicator of Which Drive was Used to Boot the System */
6585 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6586 tmp[1] = ':';
6587 tmp[2] = '\0';
6588
Fred Drake4d1e64b2002-04-15 19:40:07 +00006589 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006590}
6591#endif
6592
Barry Warsaw4a342091996-12-19 23:50:02 +00006593static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006594all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006595{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006596#ifdef F_OK
6597 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006598#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006599#ifdef R_OK
6600 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006601#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006602#ifdef W_OK
6603 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006604#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006605#ifdef X_OK
6606 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006607#endif
Fred Drakec9680921999-12-13 16:37:25 +00006608#ifdef NGROUPS_MAX
6609 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6610#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006611#ifdef TMP_MAX
6612 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6613#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006614#ifdef WCONTINUED
6615 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6616#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006617#ifdef WNOHANG
6618 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006619#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006620#ifdef WUNTRACED
6621 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6622#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006623#ifdef O_RDONLY
6624 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6625#endif
6626#ifdef O_WRONLY
6627 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6628#endif
6629#ifdef O_RDWR
6630 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6631#endif
6632#ifdef O_NDELAY
6633 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6634#endif
6635#ifdef O_NONBLOCK
6636 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6637#endif
6638#ifdef O_APPEND
6639 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6640#endif
6641#ifdef O_DSYNC
6642 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6643#endif
6644#ifdef O_RSYNC
6645 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6646#endif
6647#ifdef O_SYNC
6648 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6649#endif
6650#ifdef O_NOCTTY
6651 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6652#endif
6653#ifdef O_CREAT
6654 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6655#endif
6656#ifdef O_EXCL
6657 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6658#endif
6659#ifdef O_TRUNC
6660 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6661#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006662#ifdef O_BINARY
6663 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6664#endif
6665#ifdef O_TEXT
6666 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6667#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006668#ifdef O_LARGEFILE
6669 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6670#endif
6671
Tim Peters5aa91602002-01-30 05:46:57 +00006672/* MS Windows */
6673#ifdef O_NOINHERIT
6674 /* Don't inherit in child processes. */
6675 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6676#endif
6677#ifdef _O_SHORT_LIVED
6678 /* Optimize for short life (keep in memory). */
6679 /* MS forgot to define this one with a non-underscore form too. */
6680 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6681#endif
6682#ifdef O_TEMPORARY
6683 /* Automatically delete when last handle is closed. */
6684 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6685#endif
6686#ifdef O_RANDOM
6687 /* Optimize for random access. */
6688 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6689#endif
6690#ifdef O_SEQUENTIAL
6691 /* Optimize for sequential access. */
6692 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6693#endif
6694
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006695/* GNU extensions. */
6696#ifdef O_DIRECT
6697 /* Direct disk access. */
6698 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6699#endif
6700#ifdef O_DIRECTORY
6701 /* Must be a directory. */
6702 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6703#endif
6704#ifdef O_NOFOLLOW
6705 /* Do not follow links. */
6706 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6707#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006708
Guido van Rossum246bc171999-02-01 23:54:31 +00006709#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006710#if defined(PYOS_OS2) && defined(PYCC_GCC)
6711 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6712 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6713 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6714 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6715 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6716 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6717 if (ins(d, "P_PM", (long)P_PM)) return -1;
6718 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6719 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6720 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6721 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6722 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6723 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6724 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6725 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6726 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6727 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6728 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6729 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6730 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6731#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006732 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6733 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6734 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6735 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6736 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006737#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006738#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006739
Guido van Rossumd48f2521997-12-05 22:19:34 +00006740#if defined(PYOS_OS2)
6741 if (insertvalues(d)) return -1;
6742#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006743 return 0;
6744}
6745
6746
Tim Peters5aa91602002-01-30 05:46:57 +00006747#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006748#define INITFUNC initnt
6749#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006750
6751#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006752#define INITFUNC initos2
6753#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006754
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006755#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006756#define INITFUNC initposix
6757#define MODNAME "posix"
6758#endif
6759
Mark Hammondfe51c6d2002-08-02 02:27:13 +00006760PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006761INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006762{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006763 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006764
Fred Drake4d1e64b2002-04-15 19:40:07 +00006765 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006766 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006767 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006768
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006769 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006770 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006771 Py_XINCREF(v);
6772 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006773 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006774 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006775
Fred Drake4d1e64b2002-04-15 19:40:07 +00006776 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006777 return;
6778
Fred Drake4d1e64b2002-04-15 19:40:07 +00006779 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006780 return;
6781
Fred Drake4d1e64b2002-04-15 19:40:07 +00006782 Py_INCREF(PyExc_OSError);
6783 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006784
Guido van Rossumb3d39562000-01-31 18:41:26 +00006785#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006786 if (posix_putenv_garbage == NULL)
6787 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006788#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006789
Guido van Rossum14648392001-12-08 18:02:58 +00006790 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006791 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006792 Py_INCREF((PyObject*) &StatResultType);
6793 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006794
Guido van Rossum14648392001-12-08 18:02:58 +00006795 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006796 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006797 Py_INCREF((PyObject*) &StatVFSResultType);
6798 PyModule_AddObject(m, "statvfs_result",
6799 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006800}