blob: 93f4a93ede1bf21f2a1eb86bdd735ebc3a24bd7e [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
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000132#if defined(__sgi)&&_COMPILER_VERSION>=700
133/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
134 (default) */
135extern char *ctermid_r(char *);
136#endif
137
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000138#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000155#ifdef __BORLANDC__
156extern int chmod(const char *, int);
157#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000159#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int chown(const char *, uid_t, gid_t);
161extern char *getcwd(char *, int);
162extern char *strerror(int);
163extern int link(const char *, const char *);
164extern int rename(const char *, const char *);
165extern int stat(const char *, struct stat *);
166extern int unlink(const char *);
167extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000170#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000173#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000175
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178#ifdef HAVE_UTIME_H
179#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000182#ifdef HAVE_SYS_UTIME_H
183#include <sys/utime.h>
184#define HAVE_UTIME_H /* pretend we do for the rest of this file */
185#endif /* HAVE_SYS_UTIME_H */
186
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187#ifdef HAVE_SYS_TIMES_H
188#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_PARAM_H
192#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifdef HAVE_SYS_UTSNAME_H
196#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#define NAMLEN(dirent) strlen((dirent)->d_name)
202#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#include <direct.h>
205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000218#endif
219#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <direct.h>
223#include <io.h>
224#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000225#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000226#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000228#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000229#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000230#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000231#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossumd48f2521997-12-05 22:19:34 +0000233#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000235#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236
Tim Petersbc2e10e2002-03-03 23:17:02 +0000237#ifndef MAXPATHLEN
238#define MAXPATHLEN 1024
239#endif /* MAXPATHLEN */
240
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000241#ifdef UNION_WAIT
242/* Emulate some macros on systems that have a union instead of macros */
243
244#ifndef WIFEXITED
245#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
246#endif
247
248#ifndef WEXITSTATUS
249#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
250#endif
251
252#ifndef WTERMSIG
253#define WTERMSIG(u_wait) ((u_wait).w_termsig)
254#endif
255
256#endif /* UNION_WAIT */
257
Greg Wardb48bc172000-03-01 21:51:56 +0000258/* Don't use the "_r" form if we don't need it (also, won't have a
259 prototype for it, at least on Solaris -- maybe others as well?). */
260#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
261#define USE_CTERMID_R
262#endif
263
264#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
265#define USE_TMPNAM_R
266#endif
267
Fred Drake699f3522000-06-29 21:12:41 +0000268/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000269#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000270#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000271# define STAT _stati64
272# define FSTAT _fstati64
273# define STRUCT_STAT struct _stati64
274#else
275# define STAT stat
276# define FSTAT fstat
277# define STRUCT_STAT struct stat
278#endif
279
Neal Norwitz3d949422002-04-20 13:46:43 +0000280#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
281#include <sys/mkdev.h>
282#endif
Fred Drake699f3522000-06-29 21:12:41 +0000283
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000285#ifdef WITH_NEXT_FRAMEWORK
286/* On Darwin/MacOSX a shared library or framework has no access to
287** environ directly, we must obtain it with _NSGetEnviron().
288*/
289#include <crt_externs.h>
290static char **environ;
291#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294
Barry Warsaw53699e91996-12-10 23:23:01 +0000295static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000296convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297{
Barry Warsaw53699e91996-12-10 23:23:01 +0000298 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000300 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301 if (d == NULL)
302 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000303#ifdef WITH_NEXT_FRAMEWORK
304 if (environ == NULL)
305 environ = *_NSGetEnviron();
306#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307 if (environ == NULL)
308 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000309 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000311 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000312 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 char *p = strchr(*e, '=');
314 if (p == NULL)
315 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000316 k = PyString_FromStringAndSize(*e, (int)(p-*e));
317 if (k == NULL) {
318 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000320 }
321 v = PyString_FromString(p+1);
322 if (v == NULL) {
323 PyErr_Clear();
324 Py_DECREF(k);
325 continue;
326 }
327 if (PyDict_GetItem(d, k) == NULL) {
328 if (PyDict_SetItem(d, k, v) != 0)
329 PyErr_Clear();
330 }
331 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000332 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000334#if defined(PYOS_OS2)
335 {
336 APIRET rc;
337 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
338
339 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000340 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000341 PyObject *v = PyString_FromString(buffer);
342 PyDict_SetItemString(d, "BEGINLIBPATH", v);
343 Py_DECREF(v);
344 }
345 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
346 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
347 PyObject *v = PyString_FromString(buffer);
348 PyDict_SetItemString(d, "ENDLIBPATH", v);
349 Py_DECREF(v);
350 }
351 }
352#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000353 return d;
354}
355
356
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357/* Set a POSIX-specific error from errno, and return NULL */
358
Barry Warsawd58d7641998-07-23 16:14:40 +0000359static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000360posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000361{
Barry Warsawca74da41999-02-09 19:31:45 +0000362 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363}
Barry Warsawd58d7641998-07-23 16:14:40 +0000364static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000365posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000366{
Barry Warsawca74da41999-02-09 19:31:45 +0000367 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000368}
369
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000370#ifdef Py_WIN_WIDE_FILENAMES
371static PyObject *
372posix_error_with_unicode_filename(Py_UNICODE* name)
373{
374 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
375}
376#endif /* Py_WIN_WIDE_FILENAMES */
377
378
Mark Hammondef8b6542001-05-13 08:04:26 +0000379static PyObject *
380posix_error_with_allocated_filename(char* name)
381{
382 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
383 PyMem_Free(name);
384 return rc;
385}
386
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000387#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000388static PyObject *
389win32_error(char* function, char* filename)
390{
Mark Hammond33a6da92000-08-15 00:46:38 +0000391 /* XXX We should pass the function name along in the future.
392 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000393 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000394 Windows error object, which is non-trivial.
395 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000396 errno = GetLastError();
397 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000398 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000399 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000400 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000401}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000402
403#ifdef Py_WIN_WIDE_FILENAMES
404static PyObject *
405win32_error_unicode(char* function, Py_UNICODE* filename)
406{
407 /* XXX - see win32_error for comments on 'function' */
408 errno = GetLastError();
409 if (filename)
410 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
411 else
412 return PyErr_SetFromWindowsErr(errno);
413}
414
415static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
416{
417 /* XXX Perhaps we should make this API an alias of
418 PyObject_Unicode() instead ?! */
419 if (PyUnicode_CheckExact(obj)) {
420 Py_INCREF(obj);
421 return obj;
422 }
423 if (PyUnicode_Check(obj)) {
424 /* For a Unicode subtype that's not a Unicode object,
425 return a true Unicode object with the same data. */
426 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
427 PyUnicode_GET_SIZE(obj));
428 }
429 return PyUnicode_FromEncodedObject(obj,
430 Py_FileSystemDefaultEncoding,
431 "strict");
432}
433
434#endif /* Py_WIN_WIDE_FILENAMES */
435
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000436#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000437
Guido van Rossumd48f2521997-12-05 22:19:34 +0000438#if defined(PYOS_OS2)
439/**********************************************************************
440 * Helper Function to Trim and Format OS/2 Messages
441 **********************************************************************/
442 static void
443os2_formatmsg(char *msgbuf, int msglen, char *reason)
444{
445 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
446
447 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
448 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
449
450 while (lastc > msgbuf && isspace(*lastc))
451 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
452 }
453
454 /* Add Optional Reason Text */
455 if (reason) {
456 strcat(msgbuf, " : ");
457 strcat(msgbuf, reason);
458 }
459}
460
461/**********************************************************************
462 * Decode an OS/2 Operating System Error Code
463 *
464 * A convenience function to lookup an OS/2 error code and return a
465 * text message we can use to raise a Python exception.
466 *
467 * Notes:
468 * The messages for errors returned from the OS/2 kernel reside in
469 * the file OSO001.MSG in the \OS2 directory hierarchy.
470 *
471 **********************************************************************/
472 static char *
473os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
474{
475 APIRET rc;
476 ULONG msglen;
477
478 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
479 Py_BEGIN_ALLOW_THREADS
480 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
481 errorcode, "oso001.msg", &msglen);
482 Py_END_ALLOW_THREADS
483
484 if (rc == NO_ERROR)
485 os2_formatmsg(msgbuf, msglen, reason);
486 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000487 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000488 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000489
490 return msgbuf;
491}
492
493/* Set an OS/2-specific error and return NULL. OS/2 kernel
494 errors are not in a global variable e.g. 'errno' nor are
495 they congruent with posix error numbers. */
496
497static PyObject * os2_error(int code)
498{
499 char text[1024];
500 PyObject *v;
501
502 os2_strerror(text, sizeof(text), code, "");
503
504 v = Py_BuildValue("(is)", code, text);
505 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000506 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000507 Py_DECREF(v);
508 }
509 return NULL; /* Signal to Python that an Exception is Pending */
510}
511
512#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513
514/* POSIX generic methods */
515
Barry Warsaw53699e91996-12-10 23:23:01 +0000516static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000517posix_fildes(PyObject *fdobj, int (*func)(int))
518{
519 int fd;
520 int res;
521 fd = PyObject_AsFileDescriptor(fdobj);
522 if (fd < 0)
523 return NULL;
524 Py_BEGIN_ALLOW_THREADS
525 res = (*func)(fd);
526 Py_END_ALLOW_THREADS
527 if (res < 0)
528 return posix_error();
529 Py_INCREF(Py_None);
530 return Py_None;
531}
Guido van Rossum21142a01999-01-08 21:05:37 +0000532
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000533#ifdef Py_WIN_WIDE_FILENAMES
534static int
535unicode_file_names(void)
536{
537 static int canusewide = -1;
538 if (canusewide == -1) {
539 /* As per doc for ::GetVersion(), this is the correct test for
540 the Windows NT family. */
541 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
542 }
543 return canusewide;
544}
545#endif
546
Guido van Rossum21142a01999-01-08 21:05:37 +0000547static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000548posix_1str(PyObject *args, char *format, int (*func)(const char*),
549 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000550{
Mark Hammondef8b6542001-05-13 08:04:26 +0000551 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000552 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000553#ifdef Py_WIN_WIDE_FILENAMES
554 if (unicode_file_names()) {
555 PyUnicodeObject *po;
556 if (PyArg_ParseTuple(args, wformat, &po)) {
557 Py_BEGIN_ALLOW_THREADS
558 /* PyUnicode_AS_UNICODE OK without thread
559 lock as it is a simple dereference. */
560 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
561 Py_END_ALLOW_THREADS
562 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000563 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000564 Py_INCREF(Py_None);
565 return Py_None;
566 }
567 /* Drop the argument parsing error as narrow
568 strings are also valid. */
569 PyErr_Clear();
570 }
571#else
572 /* Platforms that don't support Unicode filenames
573 shouldn't be passing these extra params */
574 assert(wformat==NULL && wfunc == NULL);
575#endif
576
Tim Peters5aa91602002-01-30 05:46:57 +0000577 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000578 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000579 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000580 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000581 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000582 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000583 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000584 return posix_error_with_allocated_filename(path1);
585 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000586 Py_INCREF(Py_None);
587 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000588}
589
Barry Warsaw53699e91996-12-10 23:23:01 +0000590static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000591posix_2str(PyObject *args,
592 char *format,
593 int (*func)(const char *, const char *),
594 char *wformat,
595 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000596{
Mark Hammondef8b6542001-05-13 08:04:26 +0000597 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000598 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000599#ifdef Py_WIN_WIDE_FILENAMES
600 if (unicode_file_names()) {
601 PyObject *po1;
602 PyObject *po2;
603 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
604 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
605 PyObject *wpath1;
606 PyObject *wpath2;
607 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
608 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
609 if (!wpath1 || !wpath2) {
610 Py_XDECREF(wpath1);
611 Py_XDECREF(wpath2);
612 return NULL;
613 }
614 Py_BEGIN_ALLOW_THREADS
615 /* PyUnicode_AS_UNICODE OK without thread
616 lock as it is a simple dereference. */
617 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
618 PyUnicode_AS_UNICODE(wpath2));
619 Py_END_ALLOW_THREADS
620 Py_XDECREF(wpath1);
621 Py_XDECREF(wpath2);
622 if (res != 0)
623 return posix_error();
624 Py_INCREF(Py_None);
625 return Py_None;
626 }
627 /* Else flow through as neither is Unicode. */
628 }
629 /* Drop the argument parsing error as narrow
630 strings are also valid. */
631 PyErr_Clear();
632 }
633#else
634 /* Platforms that don't support Unicode filenames
635 shouldn't be passing these extra params */
636 assert(wformat==NULL && wfunc == NULL);
637#endif
638
Mark Hammondef8b6542001-05-13 08:04:26 +0000639 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000640 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000641 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000642 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000643 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000644 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000645 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000646 PyMem_Free(path1);
647 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000648 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000649 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000650 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000651 Py_INCREF(Py_None);
652 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000653}
654
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000655PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000656"stat_result: Result from stat or lstat.\n\n\
657This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000658 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000659or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
660\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000661Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000662they are available as attributes only.\n\
663\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000664See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000665
666static PyStructSequence_Field stat_result_fields[] = {
667 {"st_mode", "protection bits"},
668 {"st_ino", "inode"},
669 {"st_dev", "device"},
670 {"st_nlink", "number of hard links"},
671 {"st_uid", "user ID of owner"},
672 {"st_gid", "group ID of owner"},
673 {"st_size", "total size, in bytes"},
674 {"st_atime", "time of last access"},
675 {"st_mtime", "time of last modification"},
676 {"st_ctime", "time of last change"},
677#ifdef HAVE_ST_BLKSIZE
678 {"st_blksize", "blocksize for filesystem I/O"},
679#endif
680#ifdef HAVE_ST_BLOCKS
681 {"st_blocks", "number of blocks allocated"},
682#endif
683#ifdef HAVE_ST_RDEV
684 {"st_rdev", "device type (if inode device)"},
685#endif
686 {0}
687};
688
689#ifdef HAVE_ST_BLKSIZE
690#define ST_BLKSIZE_IDX 10
691#else
692#define ST_BLKSIZE_IDX 9
693#endif
694
695#ifdef HAVE_ST_BLOCKS
696#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
697#else
698#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
699#endif
700
701#ifdef HAVE_ST_RDEV
702#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
703#else
704#define ST_RDEV_IDX ST_BLOCKS_IDX
705#endif
706
707static PyStructSequence_Desc stat_result_desc = {
708 "stat_result", /* name */
709 stat_result__doc__, /* doc */
710 stat_result_fields,
711 10
712};
713
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000714PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000715"statvfs_result: Result from statvfs or fstatvfs.\n\n\
716This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000717 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000718or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000719\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000720See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000721
722static PyStructSequence_Field statvfs_result_fields[] = {
723 {"f_bsize", },
724 {"f_frsize", },
725 {"f_blocks", },
726 {"f_bfree", },
727 {"f_bavail", },
728 {"f_files", },
729 {"f_ffree", },
730 {"f_favail", },
731 {"f_flag", },
732 {"f_namemax",},
733 {0}
734};
735
736static PyStructSequence_Desc statvfs_result_desc = {
737 "statvfs_result", /* name */
738 statvfs_result__doc__, /* doc */
739 statvfs_result_fields,
740 10
741};
742
743static PyTypeObject StatResultType;
744static PyTypeObject StatVFSResultType;
745
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000746static void
747fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
748{
749 PyObject *val;
Martin v. Löwisa32c9942002-09-09 16:17:47 +0000750 val = PyFloat_FromDouble(sec + 1e-9*nsec);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000751 PyStructSequence_SET_ITEM(v, index, val);
752}
753
Tim Peters5aa91602002-01-30 05:46:57 +0000754/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000755 (used by posix_stat() and posix_fstat()) */
756static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000757_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000758{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000759 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000760 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000761 if (v == NULL)
762 return NULL;
763
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000764 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000765#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000766 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000767 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000768#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000769 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000770#endif
771#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000772 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000773 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000774#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000775 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000776#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000777 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
778 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
779 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000780#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000781 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000782 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000783#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000784 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000785#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000786
787#ifdef HAVE_STAT_TV_NSEC
788 ansec = st.st_atim.tv_nsec;
789 mnsec = st.st_mtim.tv_nsec;
790 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000791#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000792 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000793#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000794 fill_time(v, 7, st.st_atime, ansec);
795 fill_time(v, 8, st.st_mtime, mnsec);
796 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000797
798#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000799 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000800 PyInt_FromLong((long)st.st_blksize));
801#endif
802#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000803 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000804 PyInt_FromLong((long)st.st_blocks));
805#endif
806#ifdef HAVE_ST_RDEV
807 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
808 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000809#endif
810
811 if (PyErr_Occurred()) {
812 Py_DECREF(v);
813 return NULL;
814 }
815
816 return v;
817}
818
Barry Warsaw53699e91996-12-10 23:23:01 +0000819static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000820posix_do_stat(PyObject *self, PyObject *args,
821 char *format,
822 int (*statfunc)(const char *, STRUCT_STAT *),
823 char *wformat,
824 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000825{
Fred Drake699f3522000-06-29 21:12:41 +0000826 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000827 char *path = NULL; /* pass this to stat; do not free() it */
828 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000829 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000830
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000831#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000832 int pathlen;
833 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000834#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000835
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000836
837#ifdef Py_WIN_WIDE_FILENAMES
838 /* If on wide-character-capable OS see if argument
839 is Unicode and if so use wide API. */
840 if (unicode_file_names()) {
841 PyUnicodeObject *po;
842 if (PyArg_ParseTuple(args, wformat, &po)) {
843 Py_UNICODE wpath[MAX_PATH+1];
844 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
845 /* the library call can blow up if the file name is too long! */
846 if (pathlen > MAX_PATH) {
847 errno = ENAMETOOLONG;
848 return posix_error();
849 }
850 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
851 /* Remove trailing slash or backslash, unless it's the current
852 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
853 */
854 if (pathlen > 0 &&
855 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
856 /* It does end with a slash -- exempt the root drive cases. */
857 /* XXX UNC root drives should also be exempted? */
858 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
859 /* leave it alone */;
860 else {
861 /* nuke the trailing backslash */
862 wpath[pathlen-1] = L'\0';
863 }
864 }
865 Py_BEGIN_ALLOW_THREADS
866 /* PyUnicode_AS_UNICODE result OK without
867 thread lock as it is a simple dereference. */
868 res = wstatfunc(wpath, &st);
869 Py_END_ALLOW_THREADS
870 if (res != 0)
871 return posix_error_with_unicode_filename(wpath);
872 return _pystat_fromstructstat(st);
873 }
874 /* Drop the argument parsing error as narrow strings
875 are also valid. */
876 PyErr_Clear();
877 }
878#endif
879
Tim Peters5aa91602002-01-30 05:46:57 +0000880 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000881 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000882 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000883 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000884
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000885#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000886 pathlen = strlen(path);
887 /* the library call can blow up if the file name is too long! */
888 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000889 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000890 errno = ENAMETOOLONG;
891 return posix_error();
892 }
893
Tim Peters500bd032001-12-19 19:05:01 +0000894 /* Remove trailing slash or backslash, unless it's the current
895 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
896 */
897 if (pathlen > 0 &&
898 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
899 /* It does end with a slash -- exempt the root drive cases. */
900 /* XXX UNC root drives should also be exempted? */
901 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
902 /* leave it alone */;
903 else {
904 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000905 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000906 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000907 path = pathcopy;
908 }
909 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000910#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000911
Barry Warsaw53699e91996-12-10 23:23:01 +0000912 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000913 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000914 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000915 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000916 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000917
Tim Peters500bd032001-12-19 19:05:01 +0000918 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000919 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920}
921
922
923/* POSIX methods */
924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000925PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000926"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000927Use the real uid/gid to test for access to a path. Note that most\n\
928operations will use the effective uid/gid, therefore this routine can\n\
929be used in a suid/sgid environment to test if the invoking user has the\n\
930specified access to the path. The mode argument can be F_OK to test\n\
931existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000932
933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000934posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000935{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000936 char *path;
937 int mode;
938 int res;
939
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000940 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000941 return NULL;
942 Py_BEGIN_ALLOW_THREADS
943 res = access(path, mode);
944 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +0000945 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000946}
947
Guido van Rossumd371ff11999-01-25 16:12:23 +0000948#ifndef F_OK
949#define F_OK 0
950#endif
951#ifndef R_OK
952#define R_OK 4
953#endif
954#ifndef W_OK
955#define W_OK 2
956#endif
957#ifndef X_OK
958#define X_OK 1
959#endif
960
961#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000962PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000963"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000964Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000965
966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000967posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000968{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000969 int id;
970 char *ret;
971
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000972 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000973 return NULL;
974
Guido van Rossum94f6f721999-01-06 18:42:14 +0000975 ret = ttyname(id);
976 if (ret == NULL)
977 return(posix_error());
978 return(PyString_FromString(ret));
979}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000980#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000981
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000982#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000983PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000984"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000985Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000986
987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000988posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000989{
990 char *ret;
991 char buffer[L_ctermid];
992
993 if (!PyArg_ParseTuple(args, ":ctermid"))
994 return NULL;
995
Greg Wardb48bc172000-03-01 21:51:56 +0000996#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000997 ret = ctermid_r(buffer);
998#else
999 ret = ctermid(buffer);
1000#endif
1001 if (ret == NULL)
1002 return(posix_error());
1003 return(PyString_FromString(buffer));
1004}
1005#endif
1006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001007PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001008"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001009Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001010
Barry Warsaw53699e91996-12-10 23:23:01 +00001011static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001012posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001013{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001014#ifdef MS_WINDOWS
1015 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1016#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1017 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001018#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001019 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001020#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001021}
1022
Fred Drake4d1e64b2002-04-15 19:40:07 +00001023#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001024PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001025"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001026Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001027opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001028
1029static PyObject *
1030posix_fchdir(PyObject *self, PyObject *fdobj)
1031{
1032 return posix_fildes(fdobj, fchdir);
1033}
1034#endif /* HAVE_FCHDIR */
1035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001037PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001038"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001039Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001040
Barry Warsaw53699e91996-12-10 23:23:01 +00001041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001042posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001043{
Mark Hammondef8b6542001-05-13 08:04:26 +00001044 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001045 int i;
1046 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001047 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001048 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001049 return NULL;
1050 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001051 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001052 Py_END_ALLOW_THREADS
1053 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001054 return posix_error_with_allocated_filename(path);
1055 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001056 Py_INCREF(Py_None);
1057 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001058}
1059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001060
Martin v. Löwis244edc82001-10-04 22:44:26 +00001061#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001062PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001063"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001064Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001065
1066static PyObject *
1067posix_chroot(PyObject *self, PyObject *args)
1068{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001069 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001070}
1071#endif
1072
Guido van Rossum21142a01999-01-08 21:05:37 +00001073#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001074PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001075"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001076force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001077
1078static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001079posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001080{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001081 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001082}
1083#endif /* HAVE_FSYNC */
1084
1085#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001086
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001087#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001088extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1089#endif
1090
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001091PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001092"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001093force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001094 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001095
1096static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001097posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001098{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001099 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001100}
1101#endif /* HAVE_FDATASYNC */
1102
1103
Fredrik Lundh10723342000-07-10 16:38:09 +00001104#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001105PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001106"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001107Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001108
Barry Warsaw53699e91996-12-10 23:23:01 +00001109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001110posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001111{
Mark Hammondef8b6542001-05-13 08:04:26 +00001112 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001113 int uid, gid;
1114 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001115 if (!PyArg_ParseTuple(args, "etii:chown",
1116 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001117 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001118 return NULL;
1119 Py_BEGIN_ALLOW_THREADS
1120 res = chown(path, (uid_t) uid, (gid_t) gid);
1121 Py_END_ALLOW_THREADS
1122 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001123 return posix_error_with_allocated_filename(path);
1124 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001125 Py_INCREF(Py_None);
1126 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001127}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001128#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001129
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001130#ifdef HAVE_LCHOWN
1131PyDoc_STRVAR(posix_lchown__doc__,
1132"lchown(path, uid, gid)\n\n\
1133Change the owner and group id of path to the numeric uid and gid.\n\
1134This function will not follow symbolic links.");
1135
1136static PyObject *
1137posix_lchown(PyObject *self, PyObject *args)
1138{
1139 char *path = NULL;
1140 int uid, gid;
1141 int res;
1142 if (!PyArg_ParseTuple(args, "etii:lchown",
1143 Py_FileSystemDefaultEncoding, &path,
1144 &uid, &gid))
1145 return NULL;
1146 Py_BEGIN_ALLOW_THREADS
1147 res = lchown(path, (uid_t) uid, (gid_t) gid);
1148 Py_END_ALLOW_THREADS
1149 if (res < 0)
1150 return posix_error_with_allocated_filename(path);
1151 PyMem_Free(path);
1152 Py_INCREF(Py_None);
1153 return Py_None;
1154}
1155#endif /* HAVE_LCHOWN */
1156
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001157
Guido van Rossum36bc6801995-06-14 22:54:23 +00001158#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001159PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001160"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001161Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001162
Barry Warsaw53699e91996-12-10 23:23:01 +00001163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001164posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001165{
1166 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001167 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001168 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001169 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001170 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001171#if defined(PYOS_OS2) && defined(PYCC_GCC)
1172 res = _getcwd2(buf, sizeof buf);
1173#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001174 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001175#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001176 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001177 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001179 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001180}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001181
1182PyDoc_STRVAR(posix_getcwdu__doc__,
1183"getcwdu() -> path\n\n\
1184Return a unicode string representing the current working directory.");
1185
1186static PyObject *
1187posix_getcwdu(PyObject *self, PyObject *args)
1188{
1189 char buf[1026];
1190 char *res;
1191 if (!PyArg_ParseTuple(args, ":getcwd"))
1192 return NULL;
1193
1194#ifdef Py_WIN_WIDE_FILENAMES
1195 if (unicode_file_names()) {
1196 wchar_t *wres;
1197 wchar_t wbuf[1026];
1198 Py_BEGIN_ALLOW_THREADS
1199 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1200 Py_END_ALLOW_THREADS
1201 if (wres == NULL)
1202 return posix_error();
1203 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1204 }
1205#endif
1206
1207 Py_BEGIN_ALLOW_THREADS
1208#if defined(PYOS_OS2) && defined(PYCC_GCC)
1209 res = _getcwd2(buf, sizeof buf);
1210#else
1211 res = getcwd(buf, sizeof buf);
1212#endif
1213 Py_END_ALLOW_THREADS
1214 if (res == NULL)
1215 return posix_error();
1216 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1217}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001218#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001219
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001220
Guido van Rossumb6775db1994-08-01 11:34:53 +00001221#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001222PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001223"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001224Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001225
Barry Warsaw53699e91996-12-10 23:23:01 +00001226static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001227posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001228{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001229 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001230}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001231#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001233
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001234PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001235"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001236Return a list containing the names of the entries in the directory.\n\
1237\n\
1238 path: path of directory to list\n\
1239\n\
1240The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001241entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001242
Barry Warsaw53699e91996-12-10 23:23:01 +00001243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001244posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001245{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001246 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001247 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001248#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001249
Barry Warsaw53699e91996-12-10 23:23:01 +00001250 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001251 HANDLE hFindFile;
1252 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001253 /* MAX_PATH characters could mean a bigger encoded string */
1254 char namebuf[MAX_PATH*2+5];
1255 char *bufptr = namebuf;
1256 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001257
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001258#ifdef Py_WIN_WIDE_FILENAMES
1259 /* If on wide-character-capable OS see if argument
1260 is Unicode and if so use wide API. */
1261 if (unicode_file_names()) {
1262 PyUnicodeObject *po;
1263 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1264 WIN32_FIND_DATAW wFileData;
1265 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1266 Py_UNICODE wch;
1267 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1268 wnamebuf[MAX_PATH] = L'\0';
1269 len = wcslen(wnamebuf);
1270 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1271 if (wch != L'/' && wch != L'\\' && wch != L':')
1272 wnamebuf[len++] = L'/';
1273 wcscpy(wnamebuf + len, L"*.*");
1274 if ((d = PyList_New(0)) == NULL)
1275 return NULL;
1276 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1277 if (hFindFile == INVALID_HANDLE_VALUE) {
1278 errno = GetLastError();
1279 if (errno == ERROR_FILE_NOT_FOUND) {
1280 return d;
1281 }
1282 Py_DECREF(d);
1283 return win32_error_unicode("FindFirstFileW", wnamebuf);
1284 }
1285 do {
1286 if (wFileData.cFileName[0] == L'.' &&
1287 (wFileData.cFileName[1] == L'\0' ||
1288 wFileData.cFileName[1] == L'.' &&
1289 wFileData.cFileName[2] == L'\0'))
1290 continue;
1291 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1292 if (v == NULL) {
1293 Py_DECREF(d);
1294 d = NULL;
1295 break;
1296 }
1297 if (PyList_Append(d, v) != 0) {
1298 Py_DECREF(v);
1299 Py_DECREF(d);
1300 d = NULL;
1301 break;
1302 }
1303 Py_DECREF(v);
1304 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1305
1306 if (FindClose(hFindFile) == FALSE) {
1307 Py_DECREF(d);
1308 return win32_error_unicode("FindClose", wnamebuf);
1309 }
1310 return d;
1311 }
1312 /* Drop the argument parsing error as narrow strings
1313 are also valid. */
1314 PyErr_Clear();
1315 }
1316#endif
1317
Tim Peters5aa91602002-01-30 05:46:57 +00001318 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001319 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001320 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001321 if (len > 0) {
1322 char ch = namebuf[len-1];
1323 if (ch != SEP && ch != ALTSEP && ch != ':')
1324 namebuf[len++] = '/';
1325 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001326 strcpy(namebuf + len, "*.*");
1327
Barry Warsaw53699e91996-12-10 23:23:01 +00001328 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001329 return NULL;
1330
1331 hFindFile = FindFirstFile(namebuf, &FileData);
1332 if (hFindFile == INVALID_HANDLE_VALUE) {
1333 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001334 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001335 return d;
1336 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001337 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001338 }
1339 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001340 if (FileData.cFileName[0] == '.' &&
1341 (FileData.cFileName[1] == '\0' ||
1342 FileData.cFileName[1] == '.' &&
1343 FileData.cFileName[2] == '\0'))
1344 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001345 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001346 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001347 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001348 d = NULL;
1349 break;
1350 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001351 if (PyList_Append(d, v) != 0) {
1352 Py_DECREF(v);
1353 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001354 d = NULL;
1355 break;
1356 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001357 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001358 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1359
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001360 if (FindClose(hFindFile) == FALSE) {
1361 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001362 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001363 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001364
1365 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001366
Tim Peters0bb44a42000-09-15 07:44:49 +00001367#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001368
1369#ifndef MAX_PATH
1370#define MAX_PATH CCHMAXPATH
1371#endif
1372 char *name, *pt;
1373 int len;
1374 PyObject *d, *v;
1375 char namebuf[MAX_PATH+5];
1376 HDIR hdir = 1;
1377 ULONG srchcnt = 1;
1378 FILEFINDBUF3 ep;
1379 APIRET rc;
1380
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001381 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001382 return NULL;
1383 if (len >= MAX_PATH) {
1384 PyErr_SetString(PyExc_ValueError, "path too long");
1385 return NULL;
1386 }
1387 strcpy(namebuf, name);
1388 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001389 if (*pt == ALTSEP)
1390 *pt = SEP;
1391 if (namebuf[len-1] != SEP)
1392 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001393 strcpy(namebuf + len, "*.*");
1394
1395 if ((d = PyList_New(0)) == NULL)
1396 return NULL;
1397
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001398 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1399 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001400 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001401 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1402 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1403 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001404
1405 if (rc != NO_ERROR) {
1406 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001407 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001408 }
1409
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001410 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001411 do {
1412 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001413 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001414 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001415
1416 strcpy(namebuf, ep.achName);
1417
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001418 /* Leave Case of Name Alone -- In Native Form */
1419 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001420
1421 v = PyString_FromString(namebuf);
1422 if (v == NULL) {
1423 Py_DECREF(d);
1424 d = NULL;
1425 break;
1426 }
1427 if (PyList_Append(d, v) != 0) {
1428 Py_DECREF(v);
1429 Py_DECREF(d);
1430 d = NULL;
1431 break;
1432 }
1433 Py_DECREF(v);
1434 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1435 }
1436
1437 return d;
1438#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001439
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001440 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001441 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001442 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001443 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001444 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001445 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001446 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001447 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001448 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001449 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001450 closedir(dirp);
1451 return NULL;
1452 }
1453 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001454 if (ep->d_name[0] == '.' &&
1455 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001456 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001457 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001458 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001459 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001460 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001461 d = NULL;
1462 break;
1463 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001464 if (PyList_Append(d, v) != 0) {
1465 Py_DECREF(v);
1466 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001467 d = NULL;
1468 break;
1469 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001470 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001471 }
1472 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001473
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001474 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001475
Tim Peters0bb44a42000-09-15 07:44:49 +00001476#endif /* which OS */
1477} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001478
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001479#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001480/* A helper function for abspath on win32 */
1481static PyObject *
1482posix__getfullpathname(PyObject *self, PyObject *args)
1483{
1484 /* assume encoded strings wont more than double no of chars */
1485 char inbuf[MAX_PATH*2];
1486 char *inbufp = inbuf;
1487 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1488 char outbuf[MAX_PATH*2];
1489 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001490#ifdef Py_WIN_WIDE_FILENAMES
1491 if (unicode_file_names()) {
1492 PyUnicodeObject *po;
1493 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1494 Py_UNICODE woutbuf[MAX_PATH*2];
1495 Py_UNICODE *wtemp;
1496 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1497 sizeof(woutbuf)/sizeof(woutbuf[0]),
1498 woutbuf, &wtemp))
1499 return win32_error("GetFullPathName", "");
1500 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1501 }
1502 /* Drop the argument parsing error as narrow strings
1503 are also valid. */
1504 PyErr_Clear();
1505 }
1506#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001507 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1508 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001509 &insize))
1510 return NULL;
1511 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1512 outbuf, &temp))
1513 return win32_error("GetFullPathName", inbuf);
1514 return PyString_FromString(outbuf);
1515} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001516#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001517
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001518PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001519"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001520Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001521
Barry Warsaw53699e91996-12-10 23:23:01 +00001522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001523posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001524{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001525 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001526 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001527 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001528
1529#ifdef Py_WIN_WIDE_FILENAMES
1530 if (unicode_file_names()) {
1531 PyUnicodeObject *po;
1532 if (PyArg_ParseTuple(args, "U|i:mkdir", &po)) {
1533 Py_BEGIN_ALLOW_THREADS
1534 /* PyUnicode_AS_UNICODE OK without thread lock as
1535 it is a simple dereference. */
1536 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1537 Py_END_ALLOW_THREADS
1538 if (res < 0)
1539 return posix_error();
1540 Py_INCREF(Py_None);
1541 return Py_None;
1542 }
1543 /* Drop the argument parsing error as narrow strings
1544 are also valid. */
1545 PyErr_Clear();
1546 }
1547#endif
1548
Tim Peters5aa91602002-01-30 05:46:57 +00001549 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001550 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001551 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001552 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001553#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001554 res = mkdir(path);
1555#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001556 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001557#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001558 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001559 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001560 return posix_error_with_allocated_filename(path);
1561 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001562 Py_INCREF(Py_None);
1563 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001564}
1565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001566
Guido van Rossumb6775db1994-08-01 11:34:53 +00001567#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001568#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1569#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1570#include <sys/resource.h>
1571#endif
1572#endif
1573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001574PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001575"nice(inc) -> new_priority\n\n\
1576Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001577
Barry Warsaw53699e91996-12-10 23:23:01 +00001578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001579posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001580{
1581 int increment, value;
1582
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001583 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001584 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001585
1586 /* There are two flavours of 'nice': one that returns the new
1587 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001588 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1589 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001590
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001591 If we are of the nice family that returns the new priority, we
1592 need to clear errno before the call, and check if errno is filled
1593 before calling posix_error() on a returnvalue of -1, because the
1594 -1 may be the actual new priority! */
1595
1596 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001597 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001598#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001599 if (value == 0)
1600 value = getpriority(PRIO_PROCESS, 0);
1601#endif
1602 if (value == -1 && errno != 0)
1603 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001604 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001605 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001606}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001607#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001609
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001610PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001611"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001612Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001613
Barry Warsaw53699e91996-12-10 23:23:01 +00001614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001615posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001616{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001617#ifdef MS_WINDOWS
1618 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1619#else
1620 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1621#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001622}
1623
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001624
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001625PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001626"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001627Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001628
Barry Warsaw53699e91996-12-10 23:23:01 +00001629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001630posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001631{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001632#ifdef MS_WINDOWS
1633 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1634#else
1635 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1636#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001637}
1638
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001639
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001640PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001641"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001642Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001643
Barry Warsaw53699e91996-12-10 23:23:01 +00001644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001645posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001646{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001647#ifdef MS_WINDOWS
1648 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1649#else
1650 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1651#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001652}
1653
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001654
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001655#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001656PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001657"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001658Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001659
Barry Warsaw53699e91996-12-10 23:23:01 +00001660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001661posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001662{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001663 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001664 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001665 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001666 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001667 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001668 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001669 Py_END_ALLOW_THREADS
1670 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001671}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001672#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001674
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001675PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001676"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001677Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001678
Barry Warsaw53699e91996-12-10 23:23:01 +00001679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001680posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001681{
1682 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001683 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001684 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001685 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001686 if (i < 0)
1687 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001688 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001689}
1690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001691
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001692PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001693"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001694Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001695
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001696PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001697"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001698Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001699
Barry Warsaw53699e91996-12-10 23:23:01 +00001700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001701posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001702{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001703#ifdef MS_WINDOWS
1704 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1705#else
1706 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1707#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001708}
1709
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001710
Guido van Rossumb6775db1994-08-01 11:34:53 +00001711#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001712PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001713"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001714Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001715
Barry Warsaw53699e91996-12-10 23:23:01 +00001716static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001717posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001718{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001719 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001720 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001721 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001722 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001723 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001724 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001725 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001726 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001727 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001728 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001729 u.sysname,
1730 u.nodename,
1731 u.release,
1732 u.version,
1733 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001734}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001735#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001736
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001737static int
1738extract_time(PyObject *t, long* sec, long* usec)
1739{
1740 long intval;
1741 if (PyFloat_Check(t)) {
1742 double tval = PyFloat_AsDouble(t);
1743 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1744 if (!intobj)
1745 return -1;
1746 intval = PyInt_AsLong(intobj);
1747 Py_DECREF(intobj);
1748 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001749 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001750 if (*usec < 0)
1751 /* If rounding gave us a negative number,
1752 truncate. */
1753 *usec = 0;
1754 return 0;
1755 }
1756 intval = PyInt_AsLong(t);
1757 if (intval == -1 && PyErr_Occurred())
1758 return -1;
1759 *sec = intval;
1760 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001761 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001762}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001763
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001764PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001765"utime(path, (atime, utime))\n\
1766utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001767Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001768second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001769
Barry Warsaw53699e91996-12-10 23:23:01 +00001770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001771posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001772{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001773 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001774 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001775 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001776 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001777
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001778#if defined(HAVE_UTIMES)
1779 struct timeval buf[2];
1780#define ATIME buf[0].tv_sec
1781#define MTIME buf[1].tv_sec
1782#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001783/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001784 struct utimbuf buf;
1785#define ATIME buf.actime
1786#define MTIME buf.modtime
1787#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001788#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001789 time_t buf[2];
1790#define ATIME buf[0]
1791#define MTIME buf[1]
1792#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001793#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001794
Barry Warsaw3cef8562000-05-01 16:17:24 +00001795 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001796 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001797 if (arg == Py_None) {
1798 /* optional time values not given */
1799 Py_BEGIN_ALLOW_THREADS
1800 res = utime(path, NULL);
1801 Py_END_ALLOW_THREADS
1802 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001803 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001804 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001805 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001806 return NULL;
1807 }
1808 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001809 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1810 &atime, &ausec) == -1)
1811 return NULL;
1812 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1813 &mtime, &musec) == -1)
1814 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001815 ATIME = atime;
1816 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001817#ifdef HAVE_UTIMES
1818 buf[0].tv_usec = ausec;
1819 buf[1].tv_usec = musec;
1820 Py_BEGIN_ALLOW_THREADS
1821 res = utimes(path, buf);
1822 Py_END_ALLOW_THREADS
1823#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001824 Py_BEGIN_ALLOW_THREADS
1825 res = utime(path, UTIME_ARG);
1826 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001827#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00001828 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001829 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001830 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001831 Py_INCREF(Py_None);
1832 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001833#undef UTIME_ARG
1834#undef ATIME
1835#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001836}
1837
Guido van Rossum85e3b011991-06-03 12:42:10 +00001838
Guido van Rossum3b066191991-06-04 19:40:25 +00001839/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001840
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001841PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001842"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001843Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001844
Barry Warsaw53699e91996-12-10 23:23:01 +00001845static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001846posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001847{
1848 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001849 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001850 return NULL;
1851 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001852 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001853}
1854
Martin v. Löwis114619e2002-10-07 06:44:21 +00001855#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
1856static void
1857free_string_array(char **array, int count)
1858{
1859 int i;
1860 for (i = 0; i < count; i++)
1861 PyMem_Free(array[i]);
1862 PyMem_DEL(array);
1863}
1864#endif
1865
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001866
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001867#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001868PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001869"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001870Execute an executable path with arguments, replacing current process.\n\
1871\n\
1872 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001873 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001874
Barry Warsaw53699e91996-12-10 23:23:01 +00001875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001876posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001877{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001878 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001879 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001880 char **argvlist;
1881 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001882 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001883
Guido van Rossum89b33251993-10-22 14:26:06 +00001884 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001885 argv is a list or tuple of strings. */
1886
Martin v. Löwis114619e2002-10-07 06:44:21 +00001887 if (!PyArg_ParseTuple(args, "etO:execv",
1888 Py_FileSystemDefaultEncoding,
1889 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001890 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001891 if (PyList_Check(argv)) {
1892 argc = PyList_Size(argv);
1893 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001894 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001895 else if (PyTuple_Check(argv)) {
1896 argc = PyTuple_Size(argv);
1897 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001898 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001899 else {
Fred Drake661ea262000-10-24 19:57:45 +00001900 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001901 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00001902 return NULL;
1903 }
1904
1905 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001906 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001907 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001908 return NULL;
1909 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001910
Barry Warsaw53699e91996-12-10 23:23:01 +00001911 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00001912 if (argvlist == NULL) {
1913 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001914 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00001915 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001916 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00001917 if (!PyArg_Parse((*getitem)(argv, i), "et",
1918 Py_FileSystemDefaultEncoding,
1919 &argvlist[i])) {
1920 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00001921 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001922 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001923 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00001924 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001925
Guido van Rossum85e3b011991-06-03 12:42:10 +00001926 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001927 }
1928 argvlist[argc] = NULL;
1929
Guido van Rossumb6775db1994-08-01 11:34:53 +00001930#ifdef BAD_EXEC_PROTOTYPES
1931 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001932#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001933 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001934#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001935
Guido van Rossum85e3b011991-06-03 12:42:10 +00001936 /* If we get here it's definitely an error */
1937
Martin v. Löwis114619e2002-10-07 06:44:21 +00001938 free_string_array(argvlist, argc);
1939 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001940 return posix_error();
1941}
1942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001943
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001944PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001945"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001946Execute a path with arguments and environment, replacing current process.\n\
1947\n\
1948 path: path of executable file\n\
1949 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001950 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001951
Barry Warsaw53699e91996-12-10 23:23:01 +00001952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001953posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001954{
1955 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001956 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001957 char **argvlist;
1958 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001959 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001960 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001961 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00001962 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001963
1964 /* execve has three arguments: (path, argv, env), where
1965 argv is a list or tuple of strings and env is a dictionary
1966 like posix.environ. */
1967
Martin v. Löwis114619e2002-10-07 06:44:21 +00001968 if (!PyArg_ParseTuple(args, "etOO:execve",
1969 Py_FileSystemDefaultEncoding,
1970 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001971 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001972 if (PyList_Check(argv)) {
1973 argc = PyList_Size(argv);
1974 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001975 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001976 else if (PyTuple_Check(argv)) {
1977 argc = PyTuple_Size(argv);
1978 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001979 }
1980 else {
Fred Drake661ea262000-10-24 19:57:45 +00001981 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001982 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001983 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001984 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001985 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001986 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001987 }
1988
Guido van Rossum50422b42000-04-26 20:34:28 +00001989 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001990 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001991 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001992 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00001993 }
1994
Barry Warsaw53699e91996-12-10 23:23:01 +00001995 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001996 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001997 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00001998 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001999 }
2000 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002001 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002002 "et;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002003 &argvlist[i]))
2004 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002005 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002006 goto fail_1;
2007 }
2008 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002009 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002010 argvlist[argc] = NULL;
2011
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002012 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00002013 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002014 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002015 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002016 goto fail_1;
2017 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002018 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002019 keys = PyMapping_Keys(env);
2020 vals = PyMapping_Values(env);
2021 if (!keys || !vals)
2022 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002023
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002024 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002025 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002026 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002027
2028 key = PyList_GetItem(keys, pos);
2029 val = PyList_GetItem(vals, pos);
2030 if (!key || !val)
2031 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002032
Fred Drake661ea262000-10-24 19:57:45 +00002033 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
2034 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002035 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002036 goto fail_2;
2037 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002038
2039#if defined(PYOS_OS2)
2040 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2041 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2042#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002043 len = PyString_Size(key) + PyString_Size(val) + 2;
2044 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002045 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002046 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002047 goto fail_2;
2048 }
Tim Petersc8996f52001-12-03 20:41:00 +00002049 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002050 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002051#if defined(PYOS_OS2)
2052 }
2053#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002054 }
2055 envlist[envc] = 0;
2056
Guido van Rossumb6775db1994-08-01 11:34:53 +00002057
2058#ifdef BAD_EXEC_PROTOTYPES
2059 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002060#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002061 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002062#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002063
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002064 /* If we get here it's definitely an error */
2065
2066 (void) posix_error();
2067
2068 fail_2:
2069 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002070 PyMem_DEL(envlist[envc]);
2071 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002072 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002073 free_string_array(argvlist,lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002074 Py_XDECREF(vals);
2075 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002076 fail_0:
2077 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002078 return NULL;
2079}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002080#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002082
Guido van Rossuma1065681999-01-25 23:20:23 +00002083#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002084PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002085"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002086Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002087\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002088 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002089 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002090 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002091
2092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002093posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002094{
2095 char *path;
2096 PyObject *argv;
2097 char **argvlist;
2098 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002099 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002100 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002101
2102 /* spawnv has three arguments: (mode, path, argv), where
2103 argv is a list or tuple of strings. */
2104
Martin v. Löwis114619e2002-10-07 06:44:21 +00002105 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2106 Py_FileSystemDefaultEncoding,
2107 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002108 return NULL;
2109 if (PyList_Check(argv)) {
2110 argc = PyList_Size(argv);
2111 getitem = PyList_GetItem;
2112 }
2113 else if (PyTuple_Check(argv)) {
2114 argc = PyTuple_Size(argv);
2115 getitem = PyTuple_GetItem;
2116 }
2117 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00002118 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002119 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002120 return NULL;
2121 }
2122
2123 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002124 if (argvlist == NULL) {
2125 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002126 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002127 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002128 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002129 if (!PyArg_Parse((*getitem)(argv, i), "et",
2130 Py_FileSystemDefaultEncoding,
2131 &argvlist[i])) {
2132 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002133 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002134 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002135 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002136 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002137 }
2138 }
2139 argvlist[argc] = NULL;
2140
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002141#if defined(PYOS_OS2) && defined(PYCC_GCC)
2142 Py_BEGIN_ALLOW_THREADS
2143 spawnval = spawnv(mode, path, argvlist);
2144 Py_END_ALLOW_THREADS
2145#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002146 if (mode == _OLD_P_OVERLAY)
2147 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002148
Tim Peters25059d32001-12-07 20:35:43 +00002149 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002150 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002151 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002152#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002153
Martin v. Löwis114619e2002-10-07 06:44:21 +00002154 free_string_array(argvlist, argc);
2155 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002156
Fred Drake699f3522000-06-29 21:12:41 +00002157 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002158 return posix_error();
2159 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002160#if SIZEOF_LONG == SIZEOF_VOID_P
2161 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002162#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002163 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002164#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002165}
2166
2167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002168PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002169"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002170Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002171\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002172 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002173 path: path of executable file\n\
2174 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002175 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002176
2177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002178posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002179{
2180 char *path;
2181 PyObject *argv, *env;
2182 char **argvlist;
2183 char **envlist;
2184 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2185 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002186 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002187 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002188 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002189
2190 /* spawnve has four arguments: (mode, path, argv, env), where
2191 argv is a list or tuple of strings and env is a dictionary
2192 like posix.environ. */
2193
Martin v. Löwis114619e2002-10-07 06:44:21 +00002194 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2195 Py_FileSystemDefaultEncoding,
2196 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002197 return NULL;
2198 if (PyList_Check(argv)) {
2199 argc = PyList_Size(argv);
2200 getitem = PyList_GetItem;
2201 }
2202 else if (PyTuple_Check(argv)) {
2203 argc = PyTuple_Size(argv);
2204 getitem = PyTuple_GetItem;
2205 }
2206 else {
Fred Drake661ea262000-10-24 19:57:45 +00002207 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002208 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002209 }
2210 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00002211 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002212 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002213 }
2214
2215 argvlist = PyMem_NEW(char *, argc+1);
2216 if (argvlist == NULL) {
2217 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002218 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002219 }
2220 for (i = 0; i < argc; i++) {
2221 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002222 "et;spawnve() arg 2 must contain only strings",
2223 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002224 &argvlist[i]))
2225 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002226 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002227 goto fail_1;
2228 }
2229 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002230 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002231 argvlist[argc] = NULL;
2232
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002233 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00002234 envlist = PyMem_NEW(char *, i + 1);
2235 if (envlist == NULL) {
2236 PyErr_NoMemory();
2237 goto fail_1;
2238 }
2239 envc = 0;
2240 keys = PyMapping_Keys(env);
2241 vals = PyMapping_Values(env);
2242 if (!keys || !vals)
2243 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002244
Guido van Rossuma1065681999-01-25 23:20:23 +00002245 for (pos = 0; pos < i; pos++) {
2246 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002247 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002248
2249 key = PyList_GetItem(keys, pos);
2250 val = PyList_GetItem(vals, pos);
2251 if (!key || !val)
2252 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002253
Fred Drake661ea262000-10-24 19:57:45 +00002254 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
2255 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002256 {
2257 goto fail_2;
2258 }
Tim Petersc8996f52001-12-03 20:41:00 +00002259 len = PyString_Size(key) + PyString_Size(val) + 2;
2260 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002261 if (p == NULL) {
2262 PyErr_NoMemory();
2263 goto fail_2;
2264 }
Tim Petersc8996f52001-12-03 20:41:00 +00002265 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002266 envlist[envc++] = p;
2267 }
2268 envlist[envc] = 0;
2269
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002270#if defined(PYOS_OS2) && defined(PYCC_GCC)
2271 Py_BEGIN_ALLOW_THREADS
2272 spawnval = spawnve(mode, path, argvlist, envlist);
2273 Py_END_ALLOW_THREADS
2274#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002275 if (mode == _OLD_P_OVERLAY)
2276 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002277
2278 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002279 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002280 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002281#endif
Tim Peters25059d32001-12-07 20:35:43 +00002282
Fred Drake699f3522000-06-29 21:12:41 +00002283 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002284 (void) posix_error();
2285 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002286#if SIZEOF_LONG == SIZEOF_VOID_P
2287 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002288#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002289 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002290#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002291
2292 fail_2:
2293 while (--envc >= 0)
2294 PyMem_DEL(envlist[envc]);
2295 PyMem_DEL(envlist);
2296 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002297 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002298 Py_XDECREF(vals);
2299 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002300 fail_0:
2301 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002302 return res;
2303}
2304#endif /* HAVE_SPAWNV */
2305
2306
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002307#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002308PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002309"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002310Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2311\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002312Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002313
2314static PyObject *
2315posix_fork1(self, args)
2316 PyObject *self;
2317 PyObject *args;
2318{
2319 int pid;
2320 if (!PyArg_ParseTuple(args, ":fork1"))
2321 return NULL;
2322 pid = fork1();
2323 if (pid == -1)
2324 return posix_error();
2325 PyOS_AfterFork();
2326 return PyInt_FromLong((long)pid);
2327}
2328#endif
2329
2330
Guido van Rossumad0ee831995-03-01 10:34:45 +00002331#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002332PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002333"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002334Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002335Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002336
Barry Warsaw53699e91996-12-10 23:23:01 +00002337static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002338posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002339{
2340 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002341 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002342 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002343 pid = fork();
2344 if (pid == -1)
2345 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002346 if (pid == 0)
2347 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002348 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002349}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002350#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002351
Fred Drake8cef4cf2000-06-28 16:40:38 +00002352#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
2353#ifdef HAVE_PTY_H
2354#include <pty.h>
2355#else
2356#ifdef HAVE_LIBUTIL_H
2357#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002358#endif /* HAVE_LIBUTIL_H */
2359#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002360#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002361
Thomas Wouters70c21a12000-07-14 14:28:33 +00002362#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002363PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002364"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002365Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002366
2367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002368posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002369{
2370 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002371#ifndef HAVE_OPENPTY
2372 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002373#endif
2374
Fred Drake8cef4cf2000-06-28 16:40:38 +00002375 if (!PyArg_ParseTuple(args, ":openpty"))
2376 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002377
2378#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002379 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2380 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00002381#else
2382 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2383 if (slave_name == NULL)
2384 return posix_error();
2385
2386 slave_fd = open(slave_name, O_RDWR);
2387 if (slave_fd < 0)
2388 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002389#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002390
Fred Drake8cef4cf2000-06-28 16:40:38 +00002391 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002392
Fred Drake8cef4cf2000-06-28 16:40:38 +00002393}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002394#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002395
2396#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002397PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002398"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002399Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2400Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002401To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002402
2403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002404posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002405{
2406 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002407
Fred Drake8cef4cf2000-06-28 16:40:38 +00002408 if (!PyArg_ParseTuple(args, ":forkpty"))
2409 return NULL;
2410 pid = forkpty(&master_fd, NULL, NULL, NULL);
2411 if (pid == -1)
2412 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002413 if (pid == 0)
2414 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002415 return Py_BuildValue("(ii)", pid, master_fd);
2416}
2417#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002418
Guido van Rossumad0ee831995-03-01 10:34:45 +00002419#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002420PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002421"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002422Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002423
Barry Warsaw53699e91996-12-10 23:23:01 +00002424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002425posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002426{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002427 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002428 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002429 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002430}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002431#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002432
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002433
Guido van Rossumad0ee831995-03-01 10:34:45 +00002434#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002435PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002436"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002437Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002438
Barry Warsaw53699e91996-12-10 23:23:01 +00002439static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002440posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002441{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002442 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002443 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002444 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002445}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002446#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002447
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002448
Guido van Rossumad0ee831995-03-01 10:34:45 +00002449#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002450PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002451"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002452Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002453
Barry Warsaw53699e91996-12-10 23:23:01 +00002454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002455posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002456{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002457 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002458 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002459 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002460}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002461#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002462
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002463
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002464PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002465"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002466Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002467
Barry Warsaw53699e91996-12-10 23:23:01 +00002468static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002469posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002470{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002471 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002472 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002473 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002474}
2475
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002476
Fred Drakec9680921999-12-13 16:37:25 +00002477#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002478PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002479"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002480Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002481
2482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002483posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002484{
2485 PyObject *result = NULL;
2486
2487 if (PyArg_ParseTuple(args, ":getgroups")) {
2488#ifdef NGROUPS_MAX
2489#define MAX_GROUPS NGROUPS_MAX
2490#else
2491 /* defined to be 16 on Solaris7, so this should be a small number */
2492#define MAX_GROUPS 64
2493#endif
2494 gid_t grouplist[MAX_GROUPS];
2495 int n;
2496
2497 n = getgroups(MAX_GROUPS, grouplist);
2498 if (n < 0)
2499 posix_error();
2500 else {
2501 result = PyList_New(n);
2502 if (result != NULL) {
2503 PyObject *o;
2504 int i;
2505 for (i = 0; i < n; ++i) {
2506 o = PyInt_FromLong((long)grouplist[i]);
2507 if (o == NULL) {
2508 Py_DECREF(result);
2509 result = NULL;
2510 break;
2511 }
2512 PyList_SET_ITEM(result, i, o);
2513 }
2514 }
2515 }
2516 }
2517 return result;
2518}
2519#endif
2520
Martin v. Löwis606edc12002-06-13 21:09:11 +00002521#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002522PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002523"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002524Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002525
2526static PyObject *
2527posix_getpgid(PyObject *self, PyObject *args)
2528{
2529 int pid, pgid;
2530 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2531 return NULL;
2532 pgid = getpgid(pid);
2533 if (pgid < 0)
2534 return posix_error();
2535 return PyInt_FromLong((long)pgid);
2536}
2537#endif /* HAVE_GETPGID */
2538
2539
Guido van Rossumb6775db1994-08-01 11:34:53 +00002540#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002541PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002542"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002543Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002544
Barry Warsaw53699e91996-12-10 23:23:01 +00002545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002546posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002547{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002548 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002549 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002550#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002551 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002552#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002553 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002554#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002555}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002556#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002557
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002558
Guido van Rossumb6775db1994-08-01 11:34:53 +00002559#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002560PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002561"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002562Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002563
Barry Warsaw53699e91996-12-10 23:23:01 +00002564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002565posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002566{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002567 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002568 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002569#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002570 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002571#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002572 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002573#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002574 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002575 Py_INCREF(Py_None);
2576 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002577}
2578
Guido van Rossumb6775db1994-08-01 11:34:53 +00002579#endif /* HAVE_SETPGRP */
2580
Guido van Rossumad0ee831995-03-01 10:34:45 +00002581#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002582PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002583"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002584Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002585
Barry Warsaw53699e91996-12-10 23:23:01 +00002586static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002587posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002588{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002589 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002590 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002591 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002592}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002593#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002594
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002595
Fred Drake12c6e2d1999-12-14 21:25:03 +00002596#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002597PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002598"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002599Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002600
2601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002602posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002603{
2604 PyObject *result = NULL;
2605
2606 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002607 char *name;
2608 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002609
Fred Drakea30680b2000-12-06 21:24:28 +00002610 errno = 0;
2611 name = getlogin();
2612 if (name == NULL) {
2613 if (errno)
2614 posix_error();
2615 else
2616 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002617 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002618 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002619 else
2620 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002621 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002622 }
2623 return result;
2624}
2625#endif
2626
Guido van Rossumad0ee831995-03-01 10:34:45 +00002627#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002628PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002629"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002630Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002631
Barry Warsaw53699e91996-12-10 23:23:01 +00002632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002633posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002634{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002635 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002636 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002637 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002638}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002639#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002641
Guido van Rossumad0ee831995-03-01 10:34:45 +00002642#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002643PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002644"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002645Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002646
Barry Warsaw53699e91996-12-10 23:23:01 +00002647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002648posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002649{
2650 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002651 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002652 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002653#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002654 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2655 APIRET rc;
2656 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002657 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002658
2659 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2660 APIRET rc;
2661 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002662 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002663
2664 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002665 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002666#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002667 if (kill(pid, sig) == -1)
2668 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002669#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002670 Py_INCREF(Py_None);
2671 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002672}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002673#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002674
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002675#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002676PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002677"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002678Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002679
2680static PyObject *
2681posix_killpg(PyObject *self, PyObject *args)
2682{
2683 int pgid, sig;
2684 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2685 return NULL;
2686 if (killpg(pgid, sig) == -1)
2687 return posix_error();
2688 Py_INCREF(Py_None);
2689 return Py_None;
2690}
2691#endif
2692
Guido van Rossumc0125471996-06-28 18:55:32 +00002693#ifdef HAVE_PLOCK
2694
2695#ifdef HAVE_SYS_LOCK_H
2696#include <sys/lock.h>
2697#endif
2698
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002699PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002700"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002701Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002702
Barry Warsaw53699e91996-12-10 23:23:01 +00002703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002704posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002705{
2706 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002707 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002708 return NULL;
2709 if (plock(op) == -1)
2710 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002711 Py_INCREF(Py_None);
2712 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002713}
2714#endif
2715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002716
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002717#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002718PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002719"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002720Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002721
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002722#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002723#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002724static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002725async_system(const char *command)
2726{
2727 char *p, errormsg[256], args[1024];
2728 RESULTCODES rcodes;
2729 APIRET rc;
2730 char *shell = getenv("COMSPEC");
2731 if (!shell)
2732 shell = "cmd";
2733
2734 strcpy(args, shell);
2735 p = &args[ strlen(args)+1 ];
2736 strcpy(p, "/c ");
2737 strcat(p, command);
2738 p += strlen(p) + 1;
2739 *p = '\0';
2740
2741 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002742 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002743 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002744 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002745 &rcodes, shell);
2746 return rc;
2747}
2748
Guido van Rossumd48f2521997-12-05 22:19:34 +00002749static FILE *
2750popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002751{
2752 HFILE rhan, whan;
2753 FILE *retfd = NULL;
2754 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2755
Guido van Rossumd48f2521997-12-05 22:19:34 +00002756 if (rc != NO_ERROR) {
2757 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002758 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002759 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002760
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002761 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2762 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002763
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002764 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2765 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002766
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002767 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2768 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002769
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002770 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002771 }
2772
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002773 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2774 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002775
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002776 if (rc == NO_ERROR)
2777 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2778
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002779 close(oldfd); /* And Close Saved STDOUT Handle */
2780 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002781
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002782 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2783 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002784
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002785 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2786 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002787
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002788 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2789 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002790
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002791 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002792 }
2793
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002794 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2795 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002796
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002797 if (rc == NO_ERROR)
2798 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2799
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002800 close(oldfd); /* And Close Saved STDIN Handle */
2801 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002802
Guido van Rossumd48f2521997-12-05 22:19:34 +00002803 } else {
2804 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002805 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002806 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002807}
2808
2809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002810posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002811{
2812 char *name;
2813 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002814 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002815 FILE *fp;
2816 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002817 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002818 return NULL;
2819 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002820 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002821 Py_END_ALLOW_THREADS
2822 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002823 return os2_error(err);
2824
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002825 f = PyFile_FromFile(fp, name, mode, fclose);
2826 if (f != NULL)
2827 PyFile_SetBufSize(f, bufsize);
2828 return f;
2829}
2830
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002831#elif defined(PYCC_GCC)
2832
2833/* standard posix version of popen() support */
2834static PyObject *
2835posix_popen(PyObject *self, PyObject *args)
2836{
2837 char *name;
2838 char *mode = "r";
2839 int bufsize = -1;
2840 FILE *fp;
2841 PyObject *f;
2842 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2843 return NULL;
2844 Py_BEGIN_ALLOW_THREADS
2845 fp = popen(name, mode);
2846 Py_END_ALLOW_THREADS
2847 if (fp == NULL)
2848 return posix_error();
2849 f = PyFile_FromFile(fp, name, mode, pclose);
2850 if (f != NULL)
2851 PyFile_SetBufSize(f, bufsize);
2852 return f;
2853}
2854
2855/* fork() under OS/2 has lots'o'warts
2856 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2857 * most of this code is a ripoff of the win32 code, but using the
2858 * capabilities of EMX's C library routines
2859 */
2860
2861/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2862#define POPEN_1 1
2863#define POPEN_2 2
2864#define POPEN_3 3
2865#define POPEN_4 4
2866
2867static PyObject *_PyPopen(char *, int, int, int);
2868static int _PyPclose(FILE *file);
2869
2870/*
2871 * Internal dictionary mapping popen* file pointers to process handles,
2872 * for use when retrieving the process exit code. See _PyPclose() below
2873 * for more information on this dictionary's use.
2874 */
2875static PyObject *_PyPopenProcs = NULL;
2876
2877/* os2emx version of popen2()
2878 *
2879 * The result of this function is a pipe (file) connected to the
2880 * process's stdin, and a pipe connected to the process's stdout.
2881 */
2882
2883static PyObject *
2884os2emx_popen2(PyObject *self, PyObject *args)
2885{
2886 PyObject *f;
2887 int tm=0;
2888
2889 char *cmdstring;
2890 char *mode = "t";
2891 int bufsize = -1;
2892 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2893 return NULL;
2894
2895 if (*mode == 't')
2896 tm = O_TEXT;
2897 else if (*mode != 'b') {
2898 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2899 return NULL;
2900 } else
2901 tm = O_BINARY;
2902
2903 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2904
2905 return f;
2906}
2907
2908/*
2909 * Variation on os2emx.popen2
2910 *
2911 * The result of this function is 3 pipes - the process's stdin,
2912 * stdout and stderr
2913 */
2914
2915static PyObject *
2916os2emx_popen3(PyObject *self, PyObject *args)
2917{
2918 PyObject *f;
2919 int tm = 0;
2920
2921 char *cmdstring;
2922 char *mode = "t";
2923 int bufsize = -1;
2924 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2925 return NULL;
2926
2927 if (*mode == 't')
2928 tm = O_TEXT;
2929 else if (*mode != 'b') {
2930 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2931 return NULL;
2932 } else
2933 tm = O_BINARY;
2934
2935 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2936
2937 return f;
2938}
2939
2940/*
2941 * Variation on os2emx.popen2
2942 *
2943 * The result of this function is 2 pipes - the processes stdin,
2944 * and stdout+stderr combined as a single pipe.
2945 */
2946
2947static PyObject *
2948os2emx_popen4(PyObject *self, PyObject *args)
2949{
2950 PyObject *f;
2951 int tm = 0;
2952
2953 char *cmdstring;
2954 char *mode = "t";
2955 int bufsize = -1;
2956 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2957 return NULL;
2958
2959 if (*mode == 't')
2960 tm = O_TEXT;
2961 else if (*mode != 'b') {
2962 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2963 return NULL;
2964 } else
2965 tm = O_BINARY;
2966
2967 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2968
2969 return f;
2970}
2971
2972/* a couple of structures for convenient handling of multiple
2973 * file handles and pipes
2974 */
2975struct file_ref
2976{
2977 int handle;
2978 int flags;
2979};
2980
2981struct pipe_ref
2982{
2983 int rd;
2984 int wr;
2985};
2986
2987/* The following code is derived from the win32 code */
2988
2989static PyObject *
2990_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2991{
2992 struct file_ref stdio[3];
2993 struct pipe_ref p_fd[3];
2994 FILE *p_s[3];
2995 int file_count, i, pipe_err, pipe_pid;
2996 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2997 PyObject *f, *p_f[3];
2998
2999 /* file modes for subsequent fdopen's on pipe handles */
3000 if (mode == O_TEXT)
3001 {
3002 rd_mode = "rt";
3003 wr_mode = "wt";
3004 }
3005 else
3006 {
3007 rd_mode = "rb";
3008 wr_mode = "wb";
3009 }
3010
3011 /* prepare shell references */
3012 if ((shell = getenv("EMXSHELL")) == NULL)
3013 if ((shell = getenv("COMSPEC")) == NULL)
3014 {
3015 errno = ENOENT;
3016 return posix_error();
3017 }
3018
3019 sh_name = _getname(shell);
3020 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3021 opt = "/c";
3022 else
3023 opt = "-c";
3024
3025 /* save current stdio fds + their flags, and set not inheritable */
3026 i = pipe_err = 0;
3027 while (pipe_err >= 0 && i < 3)
3028 {
3029 pipe_err = stdio[i].handle = dup(i);
3030 stdio[i].flags = fcntl(i, F_GETFD, 0);
3031 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3032 i++;
3033 }
3034 if (pipe_err < 0)
3035 {
3036 /* didn't get them all saved - clean up and bail out */
3037 int saved_err = errno;
3038 while (i-- > 0)
3039 {
3040 close(stdio[i].handle);
3041 }
3042 errno = saved_err;
3043 return posix_error();
3044 }
3045
3046 /* create pipe ends */
3047 file_count = 2;
3048 if (n == POPEN_3)
3049 file_count = 3;
3050 i = pipe_err = 0;
3051 while ((pipe_err == 0) && (i < file_count))
3052 pipe_err = pipe((int *)&p_fd[i++]);
3053 if (pipe_err < 0)
3054 {
3055 /* didn't get them all made - clean up and bail out */
3056 while (i-- > 0)
3057 {
3058 close(p_fd[i].wr);
3059 close(p_fd[i].rd);
3060 }
3061 errno = EPIPE;
3062 return posix_error();
3063 }
3064
3065 /* change the actual standard IO streams over temporarily,
3066 * making the retained pipe ends non-inheritable
3067 */
3068 pipe_err = 0;
3069
3070 /* - stdin */
3071 if (dup2(p_fd[0].rd, 0) == 0)
3072 {
3073 close(p_fd[0].rd);
3074 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3075 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3076 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3077 {
3078 close(p_fd[0].wr);
3079 pipe_err = -1;
3080 }
3081 }
3082 else
3083 {
3084 pipe_err = -1;
3085 }
3086
3087 /* - stdout */
3088 if (pipe_err == 0)
3089 {
3090 if (dup2(p_fd[1].wr, 1) == 1)
3091 {
3092 close(p_fd[1].wr);
3093 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3094 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3095 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3096 {
3097 close(p_fd[1].rd);
3098 pipe_err = -1;
3099 }
3100 }
3101 else
3102 {
3103 pipe_err = -1;
3104 }
3105 }
3106
3107 /* - stderr, as required */
3108 if (pipe_err == 0)
3109 switch (n)
3110 {
3111 case POPEN_3:
3112 {
3113 if (dup2(p_fd[2].wr, 2) == 2)
3114 {
3115 close(p_fd[2].wr);
3116 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3117 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3118 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3119 {
3120 close(p_fd[2].rd);
3121 pipe_err = -1;
3122 }
3123 }
3124 else
3125 {
3126 pipe_err = -1;
3127 }
3128 break;
3129 }
3130
3131 case POPEN_4:
3132 {
3133 if (dup2(1, 2) != 2)
3134 {
3135 pipe_err = -1;
3136 }
3137 break;
3138 }
3139 }
3140
3141 /* spawn the child process */
3142 if (pipe_err == 0)
3143 {
3144 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3145 if (pipe_pid == -1)
3146 {
3147 pipe_err = -1;
3148 }
3149 else
3150 {
3151 /* save the PID into the FILE structure
3152 * NOTE: this implementation doesn't actually
3153 * take advantage of this, but do it for
3154 * completeness - AIM Apr01
3155 */
3156 for (i = 0; i < file_count; i++)
3157 p_s[i]->_pid = pipe_pid;
3158 }
3159 }
3160
3161 /* reset standard IO to normal */
3162 for (i = 0; i < 3; i++)
3163 {
3164 dup2(stdio[i].handle, i);
3165 fcntl(i, F_SETFD, stdio[i].flags);
3166 close(stdio[i].handle);
3167 }
3168
3169 /* if any remnant problems, clean up and bail out */
3170 if (pipe_err < 0)
3171 {
3172 for (i = 0; i < 3; i++)
3173 {
3174 close(p_fd[i].rd);
3175 close(p_fd[i].wr);
3176 }
3177 errno = EPIPE;
3178 return posix_error_with_filename(cmdstring);
3179 }
3180
3181 /* build tuple of file objects to return */
3182 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3183 PyFile_SetBufSize(p_f[0], bufsize);
3184 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3185 PyFile_SetBufSize(p_f[1], bufsize);
3186 if (n == POPEN_3)
3187 {
3188 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3189 PyFile_SetBufSize(p_f[0], bufsize);
3190 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3191 }
3192 else
3193 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3194
3195 /*
3196 * Insert the files we've created into the process dictionary
3197 * all referencing the list with the process handle and the
3198 * initial number of files (see description below in _PyPclose).
3199 * Since if _PyPclose later tried to wait on a process when all
3200 * handles weren't closed, it could create a deadlock with the
3201 * child, we spend some energy here to try to ensure that we
3202 * either insert all file handles into the dictionary or none
3203 * at all. It's a little clumsy with the various popen modes
3204 * and variable number of files involved.
3205 */
3206 if (!_PyPopenProcs)
3207 {
3208 _PyPopenProcs = PyDict_New();
3209 }
3210
3211 if (_PyPopenProcs)
3212 {
3213 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3214 int ins_rc[3];
3215
3216 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3217 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3218
3219 procObj = PyList_New(2);
3220 pidObj = PyInt_FromLong((long) pipe_pid);
3221 intObj = PyInt_FromLong((long) file_count);
3222
3223 if (procObj && pidObj && intObj)
3224 {
3225 PyList_SetItem(procObj, 0, pidObj);
3226 PyList_SetItem(procObj, 1, intObj);
3227
3228 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3229 if (fileObj[0])
3230 {
3231 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3232 fileObj[0],
3233 procObj);
3234 }
3235 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3236 if (fileObj[1])
3237 {
3238 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3239 fileObj[1],
3240 procObj);
3241 }
3242 if (file_count >= 3)
3243 {
3244 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3245 if (fileObj[2])
3246 {
3247 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3248 fileObj[2],
3249 procObj);
3250 }
3251 }
3252
3253 if (ins_rc[0] < 0 || !fileObj[0] ||
3254 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3255 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3256 {
3257 /* Something failed - remove any dictionary
3258 * entries that did make it.
3259 */
3260 if (!ins_rc[0] && fileObj[0])
3261 {
3262 PyDict_DelItem(_PyPopenProcs,
3263 fileObj[0]);
3264 }
3265 if (!ins_rc[1] && fileObj[1])
3266 {
3267 PyDict_DelItem(_PyPopenProcs,
3268 fileObj[1]);
3269 }
3270 if (!ins_rc[2] && fileObj[2])
3271 {
3272 PyDict_DelItem(_PyPopenProcs,
3273 fileObj[2]);
3274 }
3275 }
3276 }
3277
3278 /*
3279 * Clean up our localized references for the dictionary keys
3280 * and value since PyDict_SetItem will Py_INCREF any copies
3281 * that got placed in the dictionary.
3282 */
3283 Py_XDECREF(procObj);
3284 Py_XDECREF(fileObj[0]);
3285 Py_XDECREF(fileObj[1]);
3286 Py_XDECREF(fileObj[2]);
3287 }
3288
3289 /* Child is launched. */
3290 return f;
3291}
3292
3293/*
3294 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3295 * exit code for the child process and return as a result of the close.
3296 *
3297 * This function uses the _PyPopenProcs dictionary in order to map the
3298 * input file pointer to information about the process that was
3299 * originally created by the popen* call that created the file pointer.
3300 * The dictionary uses the file pointer as a key (with one entry
3301 * inserted for each file returned by the original popen* call) and a
3302 * single list object as the value for all files from a single call.
3303 * The list object contains the Win32 process handle at [0], and a file
3304 * count at [1], which is initialized to the total number of file
3305 * handles using that list.
3306 *
3307 * This function closes whichever handle it is passed, and decrements
3308 * the file count in the dictionary for the process handle pointed to
3309 * by this file. On the last close (when the file count reaches zero),
3310 * this function will wait for the child process and then return its
3311 * exit code as the result of the close() operation. This permits the
3312 * files to be closed in any order - it is always the close() of the
3313 * final handle that will return the exit code.
3314 */
3315
3316 /* RED_FLAG 31-Aug-2000 Tim
3317 * This is always called (today!) between a pair of
3318 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3319 * macros. So the thread running this has no valid thread state, as
3320 * far as Python is concerned. However, this calls some Python API
3321 * functions that cannot be called safely without a valid thread
3322 * state, in particular PyDict_GetItem.
3323 * As a temporary hack (although it may last for years ...), we
3324 * *rely* on not having a valid thread state in this function, in
3325 * order to create our own "from scratch".
3326 * This will deadlock if _PyPclose is ever called by a thread
3327 * holding the global lock.
3328 * (The OS/2 EMX thread support appears to cover the case where the
3329 * lock is already held - AIM Apr01)
3330 */
3331
3332static int _PyPclose(FILE *file)
3333{
3334 int result;
3335 int exit_code;
3336 int pipe_pid;
3337 PyObject *procObj, *pidObj, *intObj, *fileObj;
3338 int file_count;
3339#ifdef WITH_THREAD
3340 PyInterpreterState* pInterpreterState;
3341 PyThreadState* pThreadState;
3342#endif
3343
3344 /* Close the file handle first, to ensure it can't block the
3345 * child from exiting if it's the last handle.
3346 */
3347 result = fclose(file);
3348
3349#ifdef WITH_THREAD
3350 /* Bootstrap a valid thread state into existence. */
3351 pInterpreterState = PyInterpreterState_New();
3352 if (!pInterpreterState) {
3353 /* Well, we're hosed now! We don't have a thread
3354 * state, so can't call a nice error routine, or raise
3355 * an exception. Just die.
3356 */
3357 Py_FatalError("unable to allocate interpreter state "
3358 "when closing popen object.");
3359 return -1; /* unreachable */
3360 }
3361 pThreadState = PyThreadState_New(pInterpreterState);
3362 if (!pThreadState) {
3363 Py_FatalError("unable to allocate thread state "
3364 "when closing popen object.");
3365 return -1; /* unreachable */
3366 }
3367 /* Grab the global lock. Note that this will deadlock if the
3368 * current thread already has the lock! (see RED_FLAG comments
3369 * before this function)
3370 */
3371 PyEval_RestoreThread(pThreadState);
3372#endif
3373
3374 if (_PyPopenProcs)
3375 {
3376 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3377 (procObj = PyDict_GetItem(_PyPopenProcs,
3378 fileObj)) != NULL &&
3379 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3380 (intObj = PyList_GetItem(procObj,1)) != NULL)
3381 {
3382 pipe_pid = (int) PyInt_AsLong(pidObj);
3383 file_count = (int) PyInt_AsLong(intObj);
3384
3385 if (file_count > 1)
3386 {
3387 /* Still other files referencing process */
3388 file_count--;
3389 PyList_SetItem(procObj,1,
3390 PyInt_FromLong((long) file_count));
3391 }
3392 else
3393 {
3394 /* Last file for this process */
3395 if (result != EOF &&
3396 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3397 {
3398 /* extract exit status */
3399 if (WIFEXITED(exit_code))
3400 {
3401 result = WEXITSTATUS(exit_code);
3402 }
3403 else
3404 {
3405 errno = EPIPE;
3406 result = -1;
3407 }
3408 }
3409 else
3410 {
3411 /* Indicate failure - this will cause the file object
3412 * to raise an I/O error and translate the last
3413 * error code from errno. We do have a problem with
3414 * last errors that overlap the normal errno table,
3415 * but that's a consistent problem with the file object.
3416 */
3417 result = -1;
3418 }
3419 }
3420
3421 /* Remove this file pointer from dictionary */
3422 PyDict_DelItem(_PyPopenProcs, fileObj);
3423
3424 if (PyDict_Size(_PyPopenProcs) == 0)
3425 {
3426 Py_DECREF(_PyPopenProcs);
3427 _PyPopenProcs = NULL;
3428 }
3429
3430 } /* if object retrieval ok */
3431
3432 Py_XDECREF(fileObj);
3433 } /* if _PyPopenProcs */
3434
3435#ifdef WITH_THREAD
3436 /* Tear down the thread & interpreter states.
3437 * Note that interpreter state clear & delete functions automatically
3438 * call the thread clear & delete functions, and indeed insist on
3439 * doing that themselves. The lock must be held during the clear, but
3440 * need not be held during the delete.
3441 */
3442 PyInterpreterState_Clear(pInterpreterState);
3443 PyEval_ReleaseThread(pThreadState);
3444 PyInterpreterState_Delete(pInterpreterState);
3445#endif
3446
3447 return result;
3448}
3449
3450#endif /* PYCC_??? */
3451
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003452#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003453
3454/*
3455 * Portable 'popen' replacement for Win32.
3456 *
3457 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3458 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003459 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003460 */
3461
3462#include <malloc.h>
3463#include <io.h>
3464#include <fcntl.h>
3465
3466/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3467#define POPEN_1 1
3468#define POPEN_2 2
3469#define POPEN_3 3
3470#define POPEN_4 4
3471
3472static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003473static int _PyPclose(FILE *file);
3474
3475/*
3476 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003477 * for use when retrieving the process exit code. See _PyPclose() below
3478 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003479 */
3480static PyObject *_PyPopenProcs = NULL;
3481
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003482
3483/* popen that works from a GUI.
3484 *
3485 * The result of this function is a pipe (file) connected to the
3486 * processes stdin or stdout, depending on the requested mode.
3487 */
3488
3489static PyObject *
3490posix_popen(PyObject *self, PyObject *args)
3491{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003492 PyObject *f, *s;
3493 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003494
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003495 char *cmdstring;
3496 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003497 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003498 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003499 return NULL;
3500
3501 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003502
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003503 if (*mode == 'r')
3504 tm = _O_RDONLY;
3505 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003506 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003507 return NULL;
3508 } else
3509 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003510
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003511 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003512 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003513 return NULL;
3514 }
3515
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003516 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003517 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003518 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003519 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003520 else
3521 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3522
3523 return f;
3524}
3525
3526/* Variation on win32pipe.popen
3527 *
3528 * The result of this function is a pipe (file) connected to the
3529 * process's stdin, and a pipe connected to the process's stdout.
3530 */
3531
3532static PyObject *
3533win32_popen2(PyObject *self, PyObject *args)
3534{
3535 PyObject *f;
3536 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003537
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003538 char *cmdstring;
3539 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003540 int bufsize = -1;
3541 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003542 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003543
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003544 if (*mode == 't')
3545 tm = _O_TEXT;
3546 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003547 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003548 return NULL;
3549 } else
3550 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003551
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003552 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003553 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003554 return NULL;
3555 }
3556
3557 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003558
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003559 return f;
3560}
3561
3562/*
3563 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003564 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003565 * The result of this function is 3 pipes - the process's stdin,
3566 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003567 */
3568
3569static PyObject *
3570win32_popen3(PyObject *self, PyObject *args)
3571{
3572 PyObject *f;
3573 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003574
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003575 char *cmdstring;
3576 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003577 int bufsize = -1;
3578 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003579 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003580
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003581 if (*mode == 't')
3582 tm = _O_TEXT;
3583 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003584 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003585 return NULL;
3586 } else
3587 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003588
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003589 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003590 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003591 return NULL;
3592 }
3593
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003594 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003595
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003596 return f;
3597}
3598
3599/*
3600 * Variation on win32pipe.popen
3601 *
Tim Peters5aa91602002-01-30 05:46:57 +00003602 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003603 * and stdout+stderr combined as a single pipe.
3604 */
3605
3606static PyObject *
3607win32_popen4(PyObject *self, PyObject *args)
3608{
3609 PyObject *f;
3610 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003611
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003612 char *cmdstring;
3613 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003614 int bufsize = -1;
3615 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003616 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003617
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003618 if (*mode == 't')
3619 tm = _O_TEXT;
3620 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003621 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003622 return NULL;
3623 } else
3624 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003625
3626 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003627 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003628 return NULL;
3629 }
3630
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003631 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003632
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003633 return f;
3634}
3635
Mark Hammond08501372001-01-31 07:30:29 +00003636static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003637_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003638 HANDLE hStdin,
3639 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003640 HANDLE hStderr,
3641 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003642{
3643 PROCESS_INFORMATION piProcInfo;
3644 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003645 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003646 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003647 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003648 int i;
3649 int x;
3650
3651 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003652 char *comshell;
3653
Tim Peters92e4dd82002-10-05 01:47:34 +00003654 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003655 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3656 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003657
3658 /* Explicitly check if we are using COMMAND.COM. If we are
3659 * then use the w9xpopen hack.
3660 */
3661 comshell = s1 + x;
3662 while (comshell >= s1 && *comshell != '\\')
3663 --comshell;
3664 ++comshell;
3665
3666 if (GetVersion() < 0x80000000 &&
3667 _stricmp(comshell, "command.com") != 0) {
3668 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003669 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003670 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003671 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003672 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003673 }
3674 else {
3675 /*
Tim Peters402d5982001-08-27 06:37:48 +00003676 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3677 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003678 */
Mark Hammond08501372001-01-31 07:30:29 +00003679 char modulepath[_MAX_PATH];
3680 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003681 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3682 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003683 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003684 x = i+1;
3685 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003686 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003687 strncat(modulepath,
3688 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003689 (sizeof(modulepath)/sizeof(modulepath[0]))
3690 -strlen(modulepath));
3691 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003692 /* Eeek - file-not-found - possibly an embedding
3693 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003694 */
Tim Peters5aa91602002-01-30 05:46:57 +00003695 strncpy(modulepath,
3696 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003697 sizeof(modulepath)/sizeof(modulepath[0]));
3698 if (modulepath[strlen(modulepath)-1] != '\\')
3699 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003700 strncat(modulepath,
3701 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003702 (sizeof(modulepath)/sizeof(modulepath[0]))
3703 -strlen(modulepath));
3704 /* No where else to look - raise an easily identifiable
3705 error, rather than leaving Windows to report
3706 "file not found" - as the user is probably blissfully
3707 unaware this shim EXE is used, and it will confuse them.
3708 (well, it confused me for a while ;-)
3709 */
3710 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003711 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003712 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003713 "for popen to work with your shell "
3714 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003715 szConsoleSpawn);
3716 return FALSE;
3717 }
3718 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003719 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003720 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003721 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003722
Tim Peters92e4dd82002-10-05 01:47:34 +00003723 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003724 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003725 /* To maintain correct argument passing semantics,
3726 we pass the command-line as it stands, and allow
3727 quoting to be applied. w9xpopen.exe will then
3728 use its argv vector, and re-quote the necessary
3729 args for the ultimate child process.
3730 */
Tim Peters75cdad52001-11-28 22:07:30 +00003731 PyOS_snprintf(
3732 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003733 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003734 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003735 s1,
3736 s3,
3737 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003738 /* Not passing CREATE_NEW_CONSOLE has been known to
3739 cause random failures on win9x. Specifically a
3740 dialog:
3741 "Your program accessed mem currently in use at xxx"
3742 and a hopeful warning about the stability of your
3743 system.
3744 Cost is Ctrl+C wont kill children, but anyone
3745 who cares can have a go!
3746 */
3747 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003748 }
3749 }
3750
3751 /* Could be an else here to try cmd.exe / command.com in the path
3752 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003753 else {
Tim Peters402d5982001-08-27 06:37:48 +00003754 PyErr_SetString(PyExc_RuntimeError,
3755 "Cannot locate a COMSPEC environment variable to "
3756 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003757 return FALSE;
3758 }
Tim Peters5aa91602002-01-30 05:46:57 +00003759
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003760 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3761 siStartInfo.cb = sizeof(STARTUPINFO);
3762 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3763 siStartInfo.hStdInput = hStdin;
3764 siStartInfo.hStdOutput = hStdout;
3765 siStartInfo.hStdError = hStderr;
3766 siStartInfo.wShowWindow = SW_HIDE;
3767
3768 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003769 s2,
3770 NULL,
3771 NULL,
3772 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003773 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003774 NULL,
3775 NULL,
3776 &siStartInfo,
3777 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003778 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003779 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003780
Mark Hammondb37a3732000-08-14 04:47:33 +00003781 /* Return process handle */
3782 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003783 return TRUE;
3784 }
Tim Peters402d5982001-08-27 06:37:48 +00003785 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003786 return FALSE;
3787}
3788
3789/* The following code is based off of KB: Q190351 */
3790
3791static PyObject *
3792_PyPopen(char *cmdstring, int mode, int n)
3793{
3794 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3795 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003796 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003797
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003798 SECURITY_ATTRIBUTES saAttr;
3799 BOOL fSuccess;
3800 int fd1, fd2, fd3;
3801 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003802 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003803 PyObject *f;
3804
3805 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3806 saAttr.bInheritHandle = TRUE;
3807 saAttr.lpSecurityDescriptor = NULL;
3808
3809 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3810 return win32_error("CreatePipe", NULL);
3811
3812 /* Create new output read handle and the input write handle. Set
3813 * the inheritance properties to FALSE. Otherwise, the child inherits
3814 * the these handles; resulting in non-closeable handles to the pipes
3815 * being created. */
3816 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003817 GetCurrentProcess(), &hChildStdinWrDup, 0,
3818 FALSE,
3819 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003820 if (!fSuccess)
3821 return win32_error("DuplicateHandle", NULL);
3822
3823 /* Close the inheritable version of ChildStdin
3824 that we're using. */
3825 CloseHandle(hChildStdinWr);
3826
3827 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3828 return win32_error("CreatePipe", NULL);
3829
3830 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003831 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3832 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003833 if (!fSuccess)
3834 return win32_error("DuplicateHandle", NULL);
3835
3836 /* Close the inheritable version of ChildStdout
3837 that we're using. */
3838 CloseHandle(hChildStdoutRd);
3839
3840 if (n != POPEN_4) {
3841 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3842 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003843 fSuccess = DuplicateHandle(GetCurrentProcess(),
3844 hChildStderrRd,
3845 GetCurrentProcess(),
3846 &hChildStderrRdDup, 0,
3847 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003848 if (!fSuccess)
3849 return win32_error("DuplicateHandle", NULL);
3850 /* Close the inheritable version of ChildStdErr that we're using. */
3851 CloseHandle(hChildStderrRd);
3852 }
Tim Peters5aa91602002-01-30 05:46:57 +00003853
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003854 switch (n) {
3855 case POPEN_1:
3856 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3857 case _O_WRONLY | _O_TEXT:
3858 /* Case for writing to child Stdin in text mode. */
3859 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3860 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003861 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003862 PyFile_SetBufSize(f, 0);
3863 /* We don't care about these pipes anymore, so close them. */
3864 CloseHandle(hChildStdoutRdDup);
3865 CloseHandle(hChildStderrRdDup);
3866 break;
3867
3868 case _O_RDONLY | _O_TEXT:
3869 /* Case for reading from child Stdout in text mode. */
3870 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3871 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003872 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003873 PyFile_SetBufSize(f, 0);
3874 /* We don't care about these pipes anymore, so close them. */
3875 CloseHandle(hChildStdinWrDup);
3876 CloseHandle(hChildStderrRdDup);
3877 break;
3878
3879 case _O_RDONLY | _O_BINARY:
3880 /* Case for readinig from child Stdout in binary mode. */
3881 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3882 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003883 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003884 PyFile_SetBufSize(f, 0);
3885 /* We don't care about these pipes anymore, so close them. */
3886 CloseHandle(hChildStdinWrDup);
3887 CloseHandle(hChildStderrRdDup);
3888 break;
3889
3890 case _O_WRONLY | _O_BINARY:
3891 /* Case for writing to child Stdin in binary mode. */
3892 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3893 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003894 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003895 PyFile_SetBufSize(f, 0);
3896 /* We don't care about these pipes anymore, so close them. */
3897 CloseHandle(hChildStdoutRdDup);
3898 CloseHandle(hChildStderrRdDup);
3899 break;
3900 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003901 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003902 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003903
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003904 case POPEN_2:
3905 case POPEN_4:
3906 {
3907 char *m1, *m2;
3908 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003909
Tim Peters7dca21e2002-08-19 00:42:29 +00003910 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003911 m1 = "r";
3912 m2 = "w";
3913 } else {
3914 m1 = "rb";
3915 m2 = "wb";
3916 }
3917
3918 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3919 f1 = _fdopen(fd1, m2);
3920 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3921 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003922 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003923 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003924 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003925 PyFile_SetBufSize(p2, 0);
3926
3927 if (n != 4)
3928 CloseHandle(hChildStderrRdDup);
3929
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003930 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003931 Py_XDECREF(p1);
3932 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003933 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003934 break;
3935 }
Tim Peters5aa91602002-01-30 05:46:57 +00003936
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003937 case POPEN_3:
3938 {
3939 char *m1, *m2;
3940 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003941
Tim Peters7dca21e2002-08-19 00:42:29 +00003942 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003943 m1 = "r";
3944 m2 = "w";
3945 } else {
3946 m1 = "rb";
3947 m2 = "wb";
3948 }
3949
3950 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3951 f1 = _fdopen(fd1, m2);
3952 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3953 f2 = _fdopen(fd2, m1);
3954 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3955 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003956 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003957 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3958 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003959 PyFile_SetBufSize(p1, 0);
3960 PyFile_SetBufSize(p2, 0);
3961 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003962 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003963 Py_XDECREF(p1);
3964 Py_XDECREF(p2);
3965 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003966 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003967 break;
3968 }
3969 }
3970
3971 if (n == POPEN_4) {
3972 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003973 hChildStdinRd,
3974 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003975 hChildStdoutWr,
3976 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003977 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003978 }
3979 else {
3980 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003981 hChildStdinRd,
3982 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003983 hChildStderrWr,
3984 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003985 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003986 }
3987
Mark Hammondb37a3732000-08-14 04:47:33 +00003988 /*
3989 * Insert the files we've created into the process dictionary
3990 * all referencing the list with the process handle and the
3991 * initial number of files (see description below in _PyPclose).
3992 * Since if _PyPclose later tried to wait on a process when all
3993 * handles weren't closed, it could create a deadlock with the
3994 * child, we spend some energy here to try to ensure that we
3995 * either insert all file handles into the dictionary or none
3996 * at all. It's a little clumsy with the various popen modes
3997 * and variable number of files involved.
3998 */
3999 if (!_PyPopenProcs) {
4000 _PyPopenProcs = PyDict_New();
4001 }
4002
4003 if (_PyPopenProcs) {
4004 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4005 int ins_rc[3];
4006
4007 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4008 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4009
4010 procObj = PyList_New(2);
4011 hProcessObj = PyLong_FromVoidPtr(hProcess);
4012 intObj = PyInt_FromLong(file_count);
4013
4014 if (procObj && hProcessObj && intObj) {
4015 PyList_SetItem(procObj,0,hProcessObj);
4016 PyList_SetItem(procObj,1,intObj);
4017
4018 fileObj[0] = PyLong_FromVoidPtr(f1);
4019 if (fileObj[0]) {
4020 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4021 fileObj[0],
4022 procObj);
4023 }
4024 if (file_count >= 2) {
4025 fileObj[1] = PyLong_FromVoidPtr(f2);
4026 if (fileObj[1]) {
4027 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4028 fileObj[1],
4029 procObj);
4030 }
4031 }
4032 if (file_count >= 3) {
4033 fileObj[2] = PyLong_FromVoidPtr(f3);
4034 if (fileObj[2]) {
4035 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4036 fileObj[2],
4037 procObj);
4038 }
4039 }
4040
4041 if (ins_rc[0] < 0 || !fileObj[0] ||
4042 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4043 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4044 /* Something failed - remove any dictionary
4045 * entries that did make it.
4046 */
4047 if (!ins_rc[0] && fileObj[0]) {
4048 PyDict_DelItem(_PyPopenProcs,
4049 fileObj[0]);
4050 }
4051 if (!ins_rc[1] && fileObj[1]) {
4052 PyDict_DelItem(_PyPopenProcs,
4053 fileObj[1]);
4054 }
4055 if (!ins_rc[2] && fileObj[2]) {
4056 PyDict_DelItem(_PyPopenProcs,
4057 fileObj[2]);
4058 }
4059 }
4060 }
Tim Peters5aa91602002-01-30 05:46:57 +00004061
Mark Hammondb37a3732000-08-14 04:47:33 +00004062 /*
4063 * Clean up our localized references for the dictionary keys
4064 * and value since PyDict_SetItem will Py_INCREF any copies
4065 * that got placed in the dictionary.
4066 */
4067 Py_XDECREF(procObj);
4068 Py_XDECREF(fileObj[0]);
4069 Py_XDECREF(fileObj[1]);
4070 Py_XDECREF(fileObj[2]);
4071 }
4072
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004073 /* Child is launched. Close the parents copy of those pipe
4074 * handles that only the child should have open. You need to
4075 * make sure that no handles to the write end of the output pipe
4076 * are maintained in this process or else the pipe will not close
4077 * when the child process exits and the ReadFile will hang. */
4078
4079 if (!CloseHandle(hChildStdinRd))
4080 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004081
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004082 if (!CloseHandle(hChildStdoutWr))
4083 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004084
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004085 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4086 return win32_error("CloseHandle", NULL);
4087
4088 return f;
4089}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004090
4091/*
4092 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4093 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004094 *
4095 * This function uses the _PyPopenProcs dictionary in order to map the
4096 * input file pointer to information about the process that was
4097 * originally created by the popen* call that created the file pointer.
4098 * The dictionary uses the file pointer as a key (with one entry
4099 * inserted for each file returned by the original popen* call) and a
4100 * single list object as the value for all files from a single call.
4101 * The list object contains the Win32 process handle at [0], and a file
4102 * count at [1], which is initialized to the total number of file
4103 * handles using that list.
4104 *
4105 * This function closes whichever handle it is passed, and decrements
4106 * the file count in the dictionary for the process handle pointed to
4107 * by this file. On the last close (when the file count reaches zero),
4108 * this function will wait for the child process and then return its
4109 * exit code as the result of the close() operation. This permits the
4110 * files to be closed in any order - it is always the close() of the
4111 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004112 */
Tim Peters736aa322000-09-01 06:51:24 +00004113
4114 /* RED_FLAG 31-Aug-2000 Tim
4115 * This is always called (today!) between a pair of
4116 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4117 * macros. So the thread running this has no valid thread state, as
4118 * far as Python is concerned. However, this calls some Python API
4119 * functions that cannot be called safely without a valid thread
4120 * state, in particular PyDict_GetItem.
4121 * As a temporary hack (although it may last for years ...), we
4122 * *rely* on not having a valid thread state in this function, in
4123 * order to create our own "from scratch".
4124 * This will deadlock if _PyPclose is ever called by a thread
4125 * holding the global lock.
4126 */
4127
Fredrik Lundh56055a42000-07-23 19:47:12 +00004128static int _PyPclose(FILE *file)
4129{
Fredrik Lundh20318932000-07-26 17:29:12 +00004130 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004131 DWORD exit_code;
4132 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004133 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4134 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004135#ifdef WITH_THREAD
4136 PyInterpreterState* pInterpreterState;
4137 PyThreadState* pThreadState;
4138#endif
4139
Fredrik Lundh20318932000-07-26 17:29:12 +00004140 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004141 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004142 */
4143 result = fclose(file);
4144
Tim Peters736aa322000-09-01 06:51:24 +00004145#ifdef WITH_THREAD
4146 /* Bootstrap a valid thread state into existence. */
4147 pInterpreterState = PyInterpreterState_New();
4148 if (!pInterpreterState) {
4149 /* Well, we're hosed now! We don't have a thread
4150 * state, so can't call a nice error routine, or raise
4151 * an exception. Just die.
4152 */
4153 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004154 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004155 return -1; /* unreachable */
4156 }
4157 pThreadState = PyThreadState_New(pInterpreterState);
4158 if (!pThreadState) {
4159 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004160 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004161 return -1; /* unreachable */
4162 }
4163 /* Grab the global lock. Note that this will deadlock if the
4164 * current thread already has the lock! (see RED_FLAG comments
4165 * before this function)
4166 */
4167 PyEval_RestoreThread(pThreadState);
4168#endif
4169
Fredrik Lundh56055a42000-07-23 19:47:12 +00004170 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004171 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4172 (procObj = PyDict_GetItem(_PyPopenProcs,
4173 fileObj)) != NULL &&
4174 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4175 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4176
4177 hProcess = PyLong_AsVoidPtr(hProcessObj);
4178 file_count = PyInt_AsLong(intObj);
4179
4180 if (file_count > 1) {
4181 /* Still other files referencing process */
4182 file_count--;
4183 PyList_SetItem(procObj,1,
4184 PyInt_FromLong(file_count));
4185 } else {
4186 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004187 if (result != EOF &&
4188 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4189 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004190 /* Possible truncation here in 16-bit environments, but
4191 * real exit codes are just the lower byte in any event.
4192 */
4193 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004194 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004195 /* Indicate failure - this will cause the file object
4196 * to raise an I/O error and translate the last Win32
4197 * error code from errno. We do have a problem with
4198 * last errors that overlap the normal errno table,
4199 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004200 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004201 if (result != EOF) {
4202 /* If the error wasn't from the fclose(), then
4203 * set errno for the file object error handling.
4204 */
4205 errno = GetLastError();
4206 }
4207 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004208 }
4209
4210 /* Free up the native handle at this point */
4211 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004212 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004213
Mark Hammondb37a3732000-08-14 04:47:33 +00004214 /* Remove this file pointer from dictionary */
4215 PyDict_DelItem(_PyPopenProcs, fileObj);
4216
4217 if (PyDict_Size(_PyPopenProcs) == 0) {
4218 Py_DECREF(_PyPopenProcs);
4219 _PyPopenProcs = NULL;
4220 }
4221
4222 } /* if object retrieval ok */
4223
4224 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004225 } /* if _PyPopenProcs */
4226
Tim Peters736aa322000-09-01 06:51:24 +00004227#ifdef WITH_THREAD
4228 /* Tear down the thread & interpreter states.
4229 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004230 * call the thread clear & delete functions, and indeed insist on
4231 * doing that themselves. The lock must be held during the clear, but
4232 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004233 */
4234 PyInterpreterState_Clear(pInterpreterState);
4235 PyEval_ReleaseThread(pThreadState);
4236 PyInterpreterState_Delete(pInterpreterState);
4237#endif
4238
Fredrik Lundh56055a42000-07-23 19:47:12 +00004239 return result;
4240}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004241
4242#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004244posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004245{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004246 char *name;
4247 char *mode = "r";
4248 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004249 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004250 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004251 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004252 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004253 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004254 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004255 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004256 if (fp == NULL)
4257 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004258 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004259 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004260 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004261 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004262}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004263
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004264#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004265#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004266
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267
Guido van Rossumb6775db1994-08-01 11:34:53 +00004268#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004269PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004270"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004271Set the current process's user id.");
4272
Barry Warsaw53699e91996-12-10 23:23:01 +00004273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004274posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004275{
4276 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004277 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004278 return NULL;
4279 if (setuid(uid) < 0)
4280 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004281 Py_INCREF(Py_None);
4282 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004283}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004284#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004285
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004286
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004287#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004288PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004289"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004290Set the current process's effective user id.");
4291
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004292static PyObject *
4293posix_seteuid (PyObject *self, PyObject *args)
4294{
4295 int euid;
4296 if (!PyArg_ParseTuple(args, "i", &euid)) {
4297 return NULL;
4298 } else if (seteuid(euid) < 0) {
4299 return posix_error();
4300 } else {
4301 Py_INCREF(Py_None);
4302 return Py_None;
4303 }
4304}
4305#endif /* HAVE_SETEUID */
4306
4307#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004308PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004309"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004310Set the current process's effective group id.");
4311
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004312static PyObject *
4313posix_setegid (PyObject *self, PyObject *args)
4314{
4315 int egid;
4316 if (!PyArg_ParseTuple(args, "i", &egid)) {
4317 return NULL;
4318 } else if (setegid(egid) < 0) {
4319 return posix_error();
4320 } else {
4321 Py_INCREF(Py_None);
4322 return Py_None;
4323 }
4324}
4325#endif /* HAVE_SETEGID */
4326
4327#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004328PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004329"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004330Set the current process's real and effective user ids.");
4331
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004332static PyObject *
4333posix_setreuid (PyObject *self, PyObject *args)
4334{
4335 int ruid, euid;
4336 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4337 return NULL;
4338 } else if (setreuid(ruid, euid) < 0) {
4339 return posix_error();
4340 } else {
4341 Py_INCREF(Py_None);
4342 return Py_None;
4343 }
4344}
4345#endif /* HAVE_SETREUID */
4346
4347#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004348PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004349"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004350Set the current process's real and effective group ids.");
4351
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004352static PyObject *
4353posix_setregid (PyObject *self, PyObject *args)
4354{
4355 int rgid, egid;
4356 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4357 return NULL;
4358 } else if (setregid(rgid, egid) < 0) {
4359 return posix_error();
4360 } else {
4361 Py_INCREF(Py_None);
4362 return Py_None;
4363 }
4364}
4365#endif /* HAVE_SETREGID */
4366
Guido van Rossumb6775db1994-08-01 11:34:53 +00004367#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004368PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004369"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004370Set the current process's group id.");
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_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004374{
4375 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004376 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004377 return NULL;
4378 if (setgid(gid) < 0)
4379 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004380 Py_INCREF(Py_None);
4381 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004382}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004383#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004384
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004385#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004386PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004387"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004388Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004389
4390static PyObject *
4391posix_setgroups(PyObject *self, PyObject *args)
4392{
4393 PyObject *groups;
4394 int i, len;
4395 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004396
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004397 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4398 return NULL;
4399 if (!PySequence_Check(groups)) {
4400 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4401 return NULL;
4402 }
4403 len = PySequence_Size(groups);
4404 if (len > MAX_GROUPS) {
4405 PyErr_SetString(PyExc_ValueError, "too many groups");
4406 return NULL;
4407 }
4408 for(i = 0; i < len; i++) {
4409 PyObject *elem;
4410 elem = PySequence_GetItem(groups, i);
4411 if (!elem)
4412 return NULL;
4413 if (!PyInt_Check(elem)) {
4414 PyErr_SetString(PyExc_TypeError,
4415 "groups must be integers");
4416 Py_DECREF(elem);
4417 return NULL;
4418 }
4419 /* XXX: check that value fits into gid_t. */
4420 grouplist[i] = PyInt_AsLong(elem);
4421 Py_DECREF(elem);
4422 }
4423
4424 if (setgroups(len, grouplist) < 0)
4425 return posix_error();
4426 Py_INCREF(Py_None);
4427 return Py_None;
4428}
4429#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004430
Guido van Rossumb6775db1994-08-01 11:34:53 +00004431#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004432PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004433"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004434Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004435
Barry Warsaw53699e91996-12-10 23:23:01 +00004436static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004437posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004438{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004439 int pid, options;
4440#ifdef UNION_WAIT
4441 union wait status;
4442#define status_i (status.w_status)
4443#else
4444 int status;
4445#define status_i status
4446#endif
4447 status_i = 0;
4448
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004449 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004450 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004451 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004452 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004453 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004454 if (pid == -1)
4455 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004456 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004457 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004458}
4459
Tim Petersab034fa2002-02-01 11:27:43 +00004460#elif defined(HAVE_CWAIT)
4461
4462/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004463PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004464"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004465"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004466
4467static PyObject *
4468posix_waitpid(PyObject *self, PyObject *args)
4469{
4470 int pid, options;
4471 int status;
4472
4473 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4474 return NULL;
4475 Py_BEGIN_ALLOW_THREADS
4476 pid = _cwait(&status, pid, options);
4477 Py_END_ALLOW_THREADS
4478 if (pid == -1)
4479 return posix_error();
4480 else
4481 /* shift the status left a byte so this is more like the
4482 POSIX waitpid */
4483 return Py_BuildValue("ii", pid, status << 8);
4484}
4485#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004486
Guido van Rossumad0ee831995-03-01 10:34:45 +00004487#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004488PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004489"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004490Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004491
Barry Warsaw53699e91996-12-10 23:23:01 +00004492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004493posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004494{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004495 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004496#ifdef UNION_WAIT
4497 union wait status;
4498#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004499#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004500 int status;
4501#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004502#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004503 if (!PyArg_ParseTuple(args, ":wait"))
4504 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004505 status_i = 0;
4506 Py_BEGIN_ALLOW_THREADS
4507 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004508 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004509 if (pid == -1)
4510 return posix_error();
4511 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004512 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004513#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004514}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004515#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004517
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004518PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004519"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004520Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004521
Barry Warsaw53699e91996-12-10 23:23:01 +00004522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004523posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004524{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004525#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004526 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004527#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004528#ifdef MS_WINDOWS
4529 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4530#else
4531 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4532#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004533#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004534}
4535
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004536
Guido van Rossumb6775db1994-08-01 11:34:53 +00004537#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004538PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004539"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004540Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004541
Barry Warsaw53699e91996-12-10 23:23:01 +00004542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004543posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004544{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004545 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004546 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004547 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004548 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004549 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004550 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004551 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004552 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004553 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004554 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004555 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004556}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004557#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004558
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004559
Guido van Rossumb6775db1994-08-01 11:34:53 +00004560#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004561PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004562"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004563Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004564
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004566posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004567{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004568 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004569}
4570#endif /* HAVE_SYMLINK */
4571
4572
4573#ifdef HAVE_TIMES
4574#ifndef HZ
4575#define HZ 60 /* Universal constant :-) */
4576#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004577
Guido van Rossumd48f2521997-12-05 22:19:34 +00004578#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4579static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004580system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004581{
4582 ULONG value = 0;
4583
4584 Py_BEGIN_ALLOW_THREADS
4585 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4586 Py_END_ALLOW_THREADS
4587
4588 return value;
4589}
4590
4591static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004592posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004593{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004594 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004595 return NULL;
4596
4597 /* Currently Only Uptime is Provided -- Others Later */
4598 return Py_BuildValue("ddddd",
4599 (double)0 /* t.tms_utime / HZ */,
4600 (double)0 /* t.tms_stime / HZ */,
4601 (double)0 /* t.tms_cutime / HZ */,
4602 (double)0 /* t.tms_cstime / HZ */,
4603 (double)system_uptime() / 1000);
4604}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004605#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004607posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004608{
4609 struct tms t;
4610 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004611 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004612 return NULL;
4613 errno = 0;
4614 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004615 if (c == (clock_t) -1)
4616 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004617 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004618 (double)t.tms_utime / HZ,
4619 (double)t.tms_stime / HZ,
4620 (double)t.tms_cutime / HZ,
4621 (double)t.tms_cstime / HZ,
4622 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004623}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004624#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004625#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004626
4627
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004628#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004629#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004631posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004632{
4633 FILETIME create, exit, kernel, user;
4634 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004635 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004636 return NULL;
4637 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004638 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4639 /* The fields of a FILETIME structure are the hi and lo part
4640 of a 64-bit value expressed in 100 nanosecond units.
4641 1e7 is one second in such units; 1e-7 the inverse.
4642 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4643 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004644 return Py_BuildValue(
4645 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004646 (double)(kernel.dwHighDateTime*429.4967296 +
4647 kernel.dwLowDateTime*1e-7),
4648 (double)(user.dwHighDateTime*429.4967296 +
4649 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004650 (double)0,
4651 (double)0,
4652 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004653}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004654#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004655
4656#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004657PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004658"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004659Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004660#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004662
Guido van Rossumb6775db1994-08-01 11:34:53 +00004663#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004664PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004665"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004666Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004667
Barry Warsaw53699e91996-12-10 23:23:01 +00004668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004669posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004670{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004671 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004672 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004673 if (setsid() < 0)
4674 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004675 Py_INCREF(Py_None);
4676 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004677}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004678#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004679
Guido van Rossumb6775db1994-08-01 11:34:53 +00004680#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004681PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004682"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004683Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004684
Barry Warsaw53699e91996-12-10 23:23:01 +00004685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004686posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004687{
4688 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004689 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004690 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004691 if (setpgid(pid, pgrp) < 0)
4692 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004693 Py_INCREF(Py_None);
4694 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004695}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004696#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004698
Guido van Rossumb6775db1994-08-01 11:34:53 +00004699#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004700PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004701"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004702Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004703
Barry Warsaw53699e91996-12-10 23:23:01 +00004704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004705posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004706{
4707 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004708 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004709 return NULL;
4710 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004711 if (pgid < 0)
4712 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004713 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004714}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004715#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004717
Guido van Rossumb6775db1994-08-01 11:34:53 +00004718#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004719PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004720"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004721Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004722
Barry Warsaw53699e91996-12-10 23:23:01 +00004723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004724posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004725{
4726 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004727 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004728 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004729 if (tcsetpgrp(fd, pgid) < 0)
4730 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004731 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004732 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004733}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004734#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004735
Guido van Rossum687dd131993-05-17 08:34:16 +00004736/* Functions acting on file descriptors */
4737
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004738PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004739"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004740Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004741
Barry Warsaw53699e91996-12-10 23:23:01 +00004742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004743posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004744{
Mark Hammondef8b6542001-05-13 08:04:26 +00004745 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004746 int flag;
4747 int mode = 0777;
4748 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004749
4750#ifdef MS_WINDOWS
4751 if (unicode_file_names()) {
4752 PyUnicodeObject *po;
4753 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4754 Py_BEGIN_ALLOW_THREADS
4755 /* PyUnicode_AS_UNICODE OK without thread
4756 lock as it is a simple dereference. */
4757 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4758 Py_END_ALLOW_THREADS
4759 if (fd < 0)
4760 return posix_error();
4761 return PyInt_FromLong((long)fd);
4762 }
4763 /* Drop the argument parsing error as narrow strings
4764 are also valid. */
4765 PyErr_Clear();
4766 }
4767#endif
4768
Tim Peters5aa91602002-01-30 05:46:57 +00004769 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004770 Py_FileSystemDefaultEncoding, &file,
4771 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004772 return NULL;
4773
Barry Warsaw53699e91996-12-10 23:23:01 +00004774 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004775 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004776 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004777 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004778 return posix_error_with_allocated_filename(file);
4779 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004780 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004781}
4782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004783
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004784PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004785"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004786Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004787
Barry Warsaw53699e91996-12-10 23:23:01 +00004788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004789posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004790{
4791 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004792 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004793 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004794 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004795 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004796 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004797 if (res < 0)
4798 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004799 Py_INCREF(Py_None);
4800 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004801}
4802
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004803
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004804PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004805"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004806Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004807
Barry Warsaw53699e91996-12-10 23:23:01 +00004808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004809posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004810{
4811 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004812 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004813 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004814 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004815 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004816 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004817 if (fd < 0)
4818 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004819 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004820}
4821
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004822
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004823PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004824"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004825Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004826
Barry Warsaw53699e91996-12-10 23:23:01 +00004827static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004828posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004829{
4830 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004831 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004832 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004833 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004834 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004835 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004836 if (res < 0)
4837 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004838 Py_INCREF(Py_None);
4839 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004840}
4841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004842
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004843PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004844"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004845Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004846
Barry Warsaw53699e91996-12-10 23:23:01 +00004847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004848posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004849{
4850 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004851#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004852 LONG_LONG pos, res;
4853#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004854 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004855#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004856 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004857 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004858 return NULL;
4859#ifdef SEEK_SET
4860 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4861 switch (how) {
4862 case 0: how = SEEK_SET; break;
4863 case 1: how = SEEK_CUR; break;
4864 case 2: how = SEEK_END; break;
4865 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004866#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004867
4868#if !defined(HAVE_LARGEFILE_SUPPORT)
4869 pos = PyInt_AsLong(posobj);
4870#else
4871 pos = PyLong_Check(posobj) ?
4872 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4873#endif
4874 if (PyErr_Occurred())
4875 return NULL;
4876
Barry Warsaw53699e91996-12-10 23:23:01 +00004877 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004878#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004879 res = _lseeki64(fd, pos, how);
4880#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004881 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004882#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004883 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004884 if (res < 0)
4885 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004886
4887#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004888 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004889#else
4890 return PyLong_FromLongLong(res);
4891#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004892}
4893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004894
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004895PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004896"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004897Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004898
Barry Warsaw53699e91996-12-10 23:23:01 +00004899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004900posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004901{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004902 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004903 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004904 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004905 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004906 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004907 if (buffer == NULL)
4908 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004909 Py_BEGIN_ALLOW_THREADS
4910 n = read(fd, PyString_AsString(buffer), size);
4911 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004912 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004913 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004914 return posix_error();
4915 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004916 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004917 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004918 return buffer;
4919}
4920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004921
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004922PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004923"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004924Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004925
Barry Warsaw53699e91996-12-10 23:23:01 +00004926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004927posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004928{
4929 int fd, size;
4930 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004931 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004932 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004933 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004934 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004935 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004936 if (size < 0)
4937 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004938 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004939}
4940
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004941
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004942PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004943"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004944Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004945
Barry Warsaw53699e91996-12-10 23:23:01 +00004946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004947posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004948{
4949 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004950 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004951 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004952 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004953 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004954 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004955 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004956 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004957 if (res != 0)
4958 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004959
Fred Drake699f3522000-06-29 21:12:41 +00004960 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004961}
4962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004963
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004964PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004965"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004966Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004967
Barry Warsaw53699e91996-12-10 23:23:01 +00004968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004969posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004970{
Guido van Rossum687dd131993-05-17 08:34:16 +00004971 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004972 char *mode = "r";
4973 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004974 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004975 PyObject *f;
4976 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004977 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004978
Barry Warsaw53699e91996-12-10 23:23:01 +00004979 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004980 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004981 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004982 if (fp == NULL)
4983 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00004984 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004985 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004986 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004987 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004988}
4989
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004990PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004991"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004992Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004993connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004994
4995static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004996posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004997{
4998 int fd;
4999 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5000 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005001 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005002}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005003
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005004#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005005PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005006"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005007Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005008
Barry Warsaw53699e91996-12-10 23:23:01 +00005009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005010posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005011{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005012#if defined(PYOS_OS2)
5013 HFILE read, write;
5014 APIRET rc;
5015
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005016 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005017 return NULL;
5018
5019 Py_BEGIN_ALLOW_THREADS
5020 rc = DosCreatePipe( &read, &write, 4096);
5021 Py_END_ALLOW_THREADS
5022 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005023 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005024
5025 return Py_BuildValue("(ii)", read, write);
5026#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005027#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005028 int fds[2];
5029 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005030 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00005031 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005032 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005033 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005034 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005035 if (res != 0)
5036 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005037 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005038#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005039 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005040 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005041 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005042 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00005043 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005044 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005045 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005046 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005047 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005048 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005049 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5050 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005051 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005052#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005053#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005054}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005055#endif /* HAVE_PIPE */
5056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005057
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005058#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005059PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005060"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005061Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005062
Barry Warsaw53699e91996-12-10 23:23:01 +00005063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005064posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005065{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005066 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005067 int mode = 0666;
5068 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005069 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005070 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005071 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005072 res = mkfifo(filename, mode);
5073 Py_END_ALLOW_THREADS
5074 if (res < 0)
5075 return posix_error();
5076 Py_INCREF(Py_None);
5077 return Py_None;
5078}
5079#endif
5080
5081
Neal Norwitz11690112002-07-30 01:08:28 +00005082#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005083PyDoc_STRVAR(posix_mknod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005084"mknod(filename, [, mode=0600, major, minor])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005085Create a filesystem node (file, device special file or named pipe)\n\
5086named filename. mode specifies both the permissions to use and the\n\
5087type of node to be created, being combined (bitwise OR) with one of\n\
5088S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
5089major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005090they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005091
5092
5093static PyObject *
5094posix_mknod(PyObject *self, PyObject *args)
5095{
5096 char *filename;
5097 int mode = 0600;
5098 int major = 0;
5099 int minor = 0;
5100 int res;
5101 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
5102 &mode, &major, &minor))
5103 return NULL;
5104 Py_BEGIN_ALLOW_THREADS
5105 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00005106 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005107 if (res < 0)
5108 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005109 Py_INCREF(Py_None);
5110 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005111}
5112#endif
5113
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005114
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005115#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005116PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005117"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005118Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005119
Barry Warsaw53699e91996-12-10 23:23:01 +00005120static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005121posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005122{
5123 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005124 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005125 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005126 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005127
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005128 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005129 return NULL;
5130
5131#if !defined(HAVE_LARGEFILE_SUPPORT)
5132 length = PyInt_AsLong(lenobj);
5133#else
5134 length = PyLong_Check(lenobj) ?
5135 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5136#endif
5137 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005138 return NULL;
5139
Barry Warsaw53699e91996-12-10 23:23:01 +00005140 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005141 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005142 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005143 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005144 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005145 return NULL;
5146 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005147 Py_INCREF(Py_None);
5148 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005149}
5150#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005151
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005152#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005153PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005154"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005155Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005156
Fred Drake762e2061999-08-26 17:23:54 +00005157/* Save putenv() parameters as values here, so we can collect them when they
5158 * get re-set with another call for the same key. */
5159static PyObject *posix_putenv_garbage;
5160
Tim Peters5aa91602002-01-30 05:46:57 +00005161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005162posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005163{
5164 char *s1, *s2;
5165 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005166 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005167 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005168
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005169 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005170 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005171
5172#if defined(PYOS_OS2)
5173 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5174 APIRET rc;
5175
5176 if (strlen(s2) == 0) /* If New Value is an Empty String */
5177 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5178
5179 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5180 if (rc != NO_ERROR)
5181 return os2_error(rc);
5182
5183 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5184 APIRET rc;
5185
5186 if (strlen(s2) == 0) /* If New Value is an Empty String */
5187 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5188
5189 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5190 if (rc != NO_ERROR)
5191 return os2_error(rc);
5192 } else {
5193#endif
5194
Fred Drake762e2061999-08-26 17:23:54 +00005195 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005196 len = strlen(s1) + strlen(s2) + 2;
5197 /* len includes space for a trailing \0; the size arg to
5198 PyString_FromStringAndSize does not count that */
5199 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005200 if (newstr == NULL)
5201 return PyErr_NoMemory();
5202 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005203 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005204 if (putenv(new)) {
5205 posix_error();
5206 return NULL;
5207 }
Fred Drake762e2061999-08-26 17:23:54 +00005208 /* Install the first arg and newstr in posix_putenv_garbage;
5209 * this will cause previous value to be collected. This has to
5210 * happen after the real putenv() call because the old value
5211 * was still accessible until then. */
5212 if (PyDict_SetItem(posix_putenv_garbage,
5213 PyTuple_GET_ITEM(args, 0), newstr)) {
5214 /* really not much we can do; just leak */
5215 PyErr_Clear();
5216 }
5217 else {
5218 Py_DECREF(newstr);
5219 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005220
5221#if defined(PYOS_OS2)
5222 }
5223#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005224 Py_INCREF(Py_None);
5225 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005226}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005227#endif /* putenv */
5228
Guido van Rossumc524d952001-10-19 01:31:59 +00005229#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005230PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005231"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005232Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005233
5234static PyObject *
5235posix_unsetenv(PyObject *self, PyObject *args)
5236{
5237 char *s1;
5238
5239 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5240 return NULL;
5241
5242 unsetenv(s1);
5243
5244 /* Remove the key from posix_putenv_garbage;
5245 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005246 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005247 * old value was still accessible until then.
5248 */
5249 if (PyDict_DelItem(posix_putenv_garbage,
5250 PyTuple_GET_ITEM(args, 0))) {
5251 /* really not much we can do; just leak */
5252 PyErr_Clear();
5253 }
5254
5255 Py_INCREF(Py_None);
5256 return Py_None;
5257}
5258#endif /* unsetenv */
5259
Guido van Rossumb6a47161997-09-15 22:54:34 +00005260#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005261PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005262"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005263Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005264
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005265static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005266posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005267{
5268 int code;
5269 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005270 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005271 return NULL;
5272 message = strerror(code);
5273 if (message == NULL) {
5274 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005275 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005276 return NULL;
5277 }
5278 return PyString_FromString(message);
5279}
5280#endif /* strerror */
5281
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005282
Guido van Rossumc9641791998-08-04 15:26:23 +00005283#ifdef HAVE_SYS_WAIT_H
5284
Fred Drake106c1a02002-04-23 15:58:02 +00005285#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005286PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005287"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005288Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005289
5290static PyObject *
5291posix_WCOREDUMP(PyObject *self, PyObject *args)
5292{
5293#ifdef UNION_WAIT
5294 union wait status;
5295#define status_i (status.w_status)
5296#else
5297 int status;
5298#define status_i status
5299#endif
5300 status_i = 0;
5301
5302 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5303 {
5304 return NULL;
5305 }
5306
5307 return PyBool_FromLong(WCOREDUMP(status));
5308#undef status_i
5309}
5310#endif /* WCOREDUMP */
5311
5312#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005313PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005314"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005315Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005316job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005317
5318static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005319posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005320{
5321#ifdef UNION_WAIT
5322 union wait status;
5323#define status_i (status.w_status)
5324#else
5325 int status;
5326#define status_i status
5327#endif
5328 status_i = 0;
5329
5330 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5331 {
5332 return NULL;
5333 }
5334
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005335 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005336#undef status_i
5337}
5338#endif /* WIFCONTINUED */
5339
Guido van Rossumc9641791998-08-04 15:26:23 +00005340#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005341PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005342"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005343Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005344
5345static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005346posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005347{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005348#ifdef UNION_WAIT
5349 union wait status;
5350#define status_i (status.w_status)
5351#else
5352 int status;
5353#define status_i status
5354#endif
5355 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005356
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005357 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005358 {
5359 return NULL;
5360 }
Tim Peters5aa91602002-01-30 05:46:57 +00005361
Fred Drake106c1a02002-04-23 15:58:02 +00005362 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005363#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005364}
5365#endif /* WIFSTOPPED */
5366
5367#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005368PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005369"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005370Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005371
5372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005373posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005374{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005375#ifdef UNION_WAIT
5376 union wait status;
5377#define status_i (status.w_status)
5378#else
5379 int status;
5380#define status_i status
5381#endif
5382 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005383
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005384 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005385 {
5386 return NULL;
5387 }
Tim Peters5aa91602002-01-30 05:46:57 +00005388
Fred Drake106c1a02002-04-23 15:58:02 +00005389 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005390#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005391}
5392#endif /* WIFSIGNALED */
5393
5394#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005395PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005396"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005397Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005398system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005399
5400static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005401posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005402{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005403#ifdef UNION_WAIT
5404 union wait status;
5405#define status_i (status.w_status)
5406#else
5407 int status;
5408#define status_i status
5409#endif
5410 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005411
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005412 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005413 {
5414 return NULL;
5415 }
Tim Peters5aa91602002-01-30 05:46:57 +00005416
Fred Drake106c1a02002-04-23 15:58:02 +00005417 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005418#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005419}
5420#endif /* WIFEXITED */
5421
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005422#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005423PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005424"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005425Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005426
5427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005428posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005429{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005430#ifdef UNION_WAIT
5431 union wait status;
5432#define status_i (status.w_status)
5433#else
5434 int status;
5435#define status_i status
5436#endif
5437 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005438
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005439 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005440 {
5441 return NULL;
5442 }
Tim Peters5aa91602002-01-30 05:46:57 +00005443
Guido van Rossumc9641791998-08-04 15:26:23 +00005444 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005445#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005446}
5447#endif /* WEXITSTATUS */
5448
5449#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005450PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005451"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005452Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005453value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005454
5455static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005456posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005457{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005458#ifdef UNION_WAIT
5459 union wait status;
5460#define status_i (status.w_status)
5461#else
5462 int status;
5463#define status_i status
5464#endif
5465 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005466
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005467 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005468 {
5469 return NULL;
5470 }
Tim Peters5aa91602002-01-30 05:46:57 +00005471
Guido van Rossumc9641791998-08-04 15:26:23 +00005472 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005473#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005474}
5475#endif /* WTERMSIG */
5476
5477#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005478PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005479"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005480Return the signal that stopped the process that provided\n\
5481the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005482
5483static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005484posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005485{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005486#ifdef UNION_WAIT
5487 union wait status;
5488#define status_i (status.w_status)
5489#else
5490 int status;
5491#define status_i status
5492#endif
5493 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005494
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005495 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005496 {
5497 return NULL;
5498 }
Tim Peters5aa91602002-01-30 05:46:57 +00005499
Guido van Rossumc9641791998-08-04 15:26:23 +00005500 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005501#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005502}
5503#endif /* WSTOPSIG */
5504
5505#endif /* HAVE_SYS_WAIT_H */
5506
5507
Guido van Rossum94f6f721999-01-06 18:42:14 +00005508#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005509#ifdef _SCO_DS
5510/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5511 needed definitions in sys/statvfs.h */
5512#define _SVID3
5513#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005514#include <sys/statvfs.h>
5515
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005516static PyObject*
5517_pystatvfs_fromstructstatvfs(struct statvfs st) {
5518 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5519 if (v == NULL)
5520 return NULL;
5521
5522#if !defined(HAVE_LARGEFILE_SUPPORT)
5523 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5524 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5525 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5526 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5527 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5528 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5529 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5530 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5531 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5532 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5533#else
5534 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5535 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005536 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005537 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005538 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005539 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5540 PyStructSequence_SET_ITEM(v, 4,
5541 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005542 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005543 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005544 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005545 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005546 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005547 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5548 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5549 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5550#endif
5551
5552 return v;
5553}
5554
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005555PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005556"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005558
5559static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005560posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005561{
5562 int fd, res;
5563 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005564
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005565 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005566 return NULL;
5567 Py_BEGIN_ALLOW_THREADS
5568 res = fstatvfs(fd, &st);
5569 Py_END_ALLOW_THREADS
5570 if (res != 0)
5571 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005572
5573 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005574}
5575#endif /* HAVE_FSTATVFS */
5576
5577
5578#if defined(HAVE_STATVFS)
5579#include <sys/statvfs.h>
5580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005581PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005582"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005583Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005584
5585static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005586posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005587{
5588 char *path;
5589 int res;
5590 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005591 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005592 return NULL;
5593 Py_BEGIN_ALLOW_THREADS
5594 res = statvfs(path, &st);
5595 Py_END_ALLOW_THREADS
5596 if (res != 0)
5597 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005598
5599 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005600}
5601#endif /* HAVE_STATVFS */
5602
5603
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005604#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005605PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005606"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005607Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005608The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005609or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005610
5611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005612posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005613{
5614 PyObject *result = NULL;
5615 char *dir = NULL;
5616 char *pfx = NULL;
5617 char *name;
5618
5619 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5620 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005621
5622 if (PyErr_Warn(PyExc_RuntimeWarning,
5623 "tempnam is a potential security risk to your program") < 0)
5624 return NULL;
5625
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005626#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005627 name = _tempnam(dir, pfx);
5628#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005629 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005630#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005631 if (name == NULL)
5632 return PyErr_NoMemory();
5633 result = PyString_FromString(name);
5634 free(name);
5635 return result;
5636}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005637#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005638
5639
5640#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005641PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005642"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005643Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005644
5645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005646posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005647{
5648 FILE *fp;
5649
5650 if (!PyArg_ParseTuple(args, ":tmpfile"))
5651 return NULL;
5652 fp = tmpfile();
5653 if (fp == NULL)
5654 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005655 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005656}
5657#endif
5658
5659
5660#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005661PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005662"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005663Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005664
5665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005666posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005667{
5668 char buffer[L_tmpnam];
5669 char *name;
5670
5671 if (!PyArg_ParseTuple(args, ":tmpnam"))
5672 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005673
5674 if (PyErr_Warn(PyExc_RuntimeWarning,
5675 "tmpnam is a potential security risk to your program") < 0)
5676 return NULL;
5677
Greg Wardb48bc172000-03-01 21:51:56 +00005678#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005679 name = tmpnam_r(buffer);
5680#else
5681 name = tmpnam(buffer);
5682#endif
5683 if (name == NULL) {
5684 PyErr_SetObject(PyExc_OSError,
5685 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005686#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005687 "unexpected NULL from tmpnam_r"
5688#else
5689 "unexpected NULL from tmpnam"
5690#endif
5691 ));
5692 return NULL;
5693 }
5694 return PyString_FromString(buffer);
5695}
5696#endif
5697
5698
Fred Drakec9680921999-12-13 16:37:25 +00005699/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5700 * It maps strings representing configuration variable names to
5701 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005702 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005703 * rarely-used constants. There are three separate tables that use
5704 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005705 *
5706 * This code is always included, even if none of the interfaces that
5707 * need it are included. The #if hackery needed to avoid it would be
5708 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005709 */
5710struct constdef {
5711 char *name;
5712 long value;
5713};
5714
Fred Drake12c6e2d1999-12-14 21:25:03 +00005715static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005716conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5717 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005718{
5719 if (PyInt_Check(arg)) {
5720 *valuep = PyInt_AS_LONG(arg);
5721 return 1;
5722 }
5723 if (PyString_Check(arg)) {
5724 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005725 size_t lo = 0;
5726 size_t mid;
5727 size_t hi = tablesize;
5728 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005729 char *confname = PyString_AS_STRING(arg);
5730 while (lo < hi) {
5731 mid = (lo + hi) / 2;
5732 cmp = strcmp(confname, table[mid].name);
5733 if (cmp < 0)
5734 hi = mid;
5735 else if (cmp > 0)
5736 lo = mid + 1;
5737 else {
5738 *valuep = table[mid].value;
5739 return 1;
5740 }
5741 }
5742 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5743 }
5744 else
5745 PyErr_SetString(PyExc_TypeError,
5746 "configuration names must be strings or integers");
5747 return 0;
5748}
5749
5750
5751#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5752static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005753#ifdef _PC_ABI_AIO_XFER_MAX
5754 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5755#endif
5756#ifdef _PC_ABI_ASYNC_IO
5757 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5758#endif
Fred Drakec9680921999-12-13 16:37:25 +00005759#ifdef _PC_ASYNC_IO
5760 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5761#endif
5762#ifdef _PC_CHOWN_RESTRICTED
5763 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5764#endif
5765#ifdef _PC_FILESIZEBITS
5766 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5767#endif
5768#ifdef _PC_LAST
5769 {"PC_LAST", _PC_LAST},
5770#endif
5771#ifdef _PC_LINK_MAX
5772 {"PC_LINK_MAX", _PC_LINK_MAX},
5773#endif
5774#ifdef _PC_MAX_CANON
5775 {"PC_MAX_CANON", _PC_MAX_CANON},
5776#endif
5777#ifdef _PC_MAX_INPUT
5778 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5779#endif
5780#ifdef _PC_NAME_MAX
5781 {"PC_NAME_MAX", _PC_NAME_MAX},
5782#endif
5783#ifdef _PC_NO_TRUNC
5784 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5785#endif
5786#ifdef _PC_PATH_MAX
5787 {"PC_PATH_MAX", _PC_PATH_MAX},
5788#endif
5789#ifdef _PC_PIPE_BUF
5790 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5791#endif
5792#ifdef _PC_PRIO_IO
5793 {"PC_PRIO_IO", _PC_PRIO_IO},
5794#endif
5795#ifdef _PC_SOCK_MAXBUF
5796 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5797#endif
5798#ifdef _PC_SYNC_IO
5799 {"PC_SYNC_IO", _PC_SYNC_IO},
5800#endif
5801#ifdef _PC_VDISABLE
5802 {"PC_VDISABLE", _PC_VDISABLE},
5803#endif
5804};
5805
Fred Drakec9680921999-12-13 16:37:25 +00005806static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005807conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005808{
5809 return conv_confname(arg, valuep, posix_constants_pathconf,
5810 sizeof(posix_constants_pathconf)
5811 / sizeof(struct constdef));
5812}
5813#endif
5814
5815#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005816PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005817"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005818Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005819If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005820
5821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005822posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005823{
5824 PyObject *result = NULL;
5825 int name, fd;
5826
Fred Drake12c6e2d1999-12-14 21:25:03 +00005827 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5828 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005829 long limit;
5830
5831 errno = 0;
5832 limit = fpathconf(fd, name);
5833 if (limit == -1 && errno != 0)
5834 posix_error();
5835 else
5836 result = PyInt_FromLong(limit);
5837 }
5838 return result;
5839}
5840#endif
5841
5842
5843#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005844PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005845"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005846Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005847If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005848
5849static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005850posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005851{
5852 PyObject *result = NULL;
5853 int name;
5854 char *path;
5855
5856 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5857 conv_path_confname, &name)) {
5858 long limit;
5859
5860 errno = 0;
5861 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005862 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005863 if (errno == EINVAL)
5864 /* could be a path or name problem */
5865 posix_error();
5866 else
5867 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005868 }
Fred Drakec9680921999-12-13 16:37:25 +00005869 else
5870 result = PyInt_FromLong(limit);
5871 }
5872 return result;
5873}
5874#endif
5875
5876#ifdef HAVE_CONFSTR
5877static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005878#ifdef _CS_ARCHITECTURE
5879 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5880#endif
5881#ifdef _CS_HOSTNAME
5882 {"CS_HOSTNAME", _CS_HOSTNAME},
5883#endif
5884#ifdef _CS_HW_PROVIDER
5885 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5886#endif
5887#ifdef _CS_HW_SERIAL
5888 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5889#endif
5890#ifdef _CS_INITTAB_NAME
5891 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5892#endif
Fred Drakec9680921999-12-13 16:37:25 +00005893#ifdef _CS_LFS64_CFLAGS
5894 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5895#endif
5896#ifdef _CS_LFS64_LDFLAGS
5897 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5898#endif
5899#ifdef _CS_LFS64_LIBS
5900 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5901#endif
5902#ifdef _CS_LFS64_LINTFLAGS
5903 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5904#endif
5905#ifdef _CS_LFS_CFLAGS
5906 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5907#endif
5908#ifdef _CS_LFS_LDFLAGS
5909 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5910#endif
5911#ifdef _CS_LFS_LIBS
5912 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5913#endif
5914#ifdef _CS_LFS_LINTFLAGS
5915 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5916#endif
Fred Draked86ed291999-12-15 15:34:33 +00005917#ifdef _CS_MACHINE
5918 {"CS_MACHINE", _CS_MACHINE},
5919#endif
Fred Drakec9680921999-12-13 16:37:25 +00005920#ifdef _CS_PATH
5921 {"CS_PATH", _CS_PATH},
5922#endif
Fred Draked86ed291999-12-15 15:34:33 +00005923#ifdef _CS_RELEASE
5924 {"CS_RELEASE", _CS_RELEASE},
5925#endif
5926#ifdef _CS_SRPC_DOMAIN
5927 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5928#endif
5929#ifdef _CS_SYSNAME
5930 {"CS_SYSNAME", _CS_SYSNAME},
5931#endif
5932#ifdef _CS_VERSION
5933 {"CS_VERSION", _CS_VERSION},
5934#endif
Fred Drakec9680921999-12-13 16:37:25 +00005935#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5936 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5937#endif
5938#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5939 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5940#endif
5941#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5942 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5943#endif
5944#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5945 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5946#endif
5947#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5948 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5949#endif
5950#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5951 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5952#endif
5953#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5954 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5955#endif
5956#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5957 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5958#endif
5959#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5960 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5961#endif
5962#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5963 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5964#endif
5965#ifdef _CS_XBS5_LP64_OFF64_LIBS
5966 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5967#endif
5968#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5969 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5970#endif
5971#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5972 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5973#endif
5974#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5975 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5976#endif
5977#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5978 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5979#endif
5980#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5981 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5982#endif
Fred Draked86ed291999-12-15 15:34:33 +00005983#ifdef _MIPS_CS_AVAIL_PROCESSORS
5984 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5985#endif
5986#ifdef _MIPS_CS_BASE
5987 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5988#endif
5989#ifdef _MIPS_CS_HOSTID
5990 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5991#endif
5992#ifdef _MIPS_CS_HW_NAME
5993 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5994#endif
5995#ifdef _MIPS_CS_NUM_PROCESSORS
5996 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5997#endif
5998#ifdef _MIPS_CS_OSREL_MAJ
5999 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6000#endif
6001#ifdef _MIPS_CS_OSREL_MIN
6002 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6003#endif
6004#ifdef _MIPS_CS_OSREL_PATCH
6005 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6006#endif
6007#ifdef _MIPS_CS_OS_NAME
6008 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6009#endif
6010#ifdef _MIPS_CS_OS_PROVIDER
6011 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6012#endif
6013#ifdef _MIPS_CS_PROCESSORS
6014 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6015#endif
6016#ifdef _MIPS_CS_SERIAL
6017 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6018#endif
6019#ifdef _MIPS_CS_VENDOR
6020 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6021#endif
Fred Drakec9680921999-12-13 16:37:25 +00006022};
6023
6024static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006025conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006026{
6027 return conv_confname(arg, valuep, posix_constants_confstr,
6028 sizeof(posix_constants_confstr)
6029 / sizeof(struct constdef));
6030}
6031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006032PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006033"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006034Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006035
6036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006037posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006038{
6039 PyObject *result = NULL;
6040 int name;
6041 char buffer[64];
6042
6043 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6044 int len = confstr(name, buffer, sizeof(buffer));
6045
Fred Drakec9680921999-12-13 16:37:25 +00006046 errno = 0;
6047 if (len == 0) {
6048 if (errno != 0)
6049 posix_error();
6050 else
6051 result = PyString_FromString("");
6052 }
6053 else {
6054 if (len >= sizeof(buffer)) {
6055 result = PyString_FromStringAndSize(NULL, len);
6056 if (result != NULL)
6057 confstr(name, PyString_AS_STRING(result), len+1);
6058 }
6059 else
6060 result = PyString_FromString(buffer);
6061 }
6062 }
6063 return result;
6064}
6065#endif
6066
6067
6068#ifdef HAVE_SYSCONF
6069static struct constdef posix_constants_sysconf[] = {
6070#ifdef _SC_2_CHAR_TERM
6071 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6072#endif
6073#ifdef _SC_2_C_BIND
6074 {"SC_2_C_BIND", _SC_2_C_BIND},
6075#endif
6076#ifdef _SC_2_C_DEV
6077 {"SC_2_C_DEV", _SC_2_C_DEV},
6078#endif
6079#ifdef _SC_2_C_VERSION
6080 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6081#endif
6082#ifdef _SC_2_FORT_DEV
6083 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6084#endif
6085#ifdef _SC_2_FORT_RUN
6086 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6087#endif
6088#ifdef _SC_2_LOCALEDEF
6089 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6090#endif
6091#ifdef _SC_2_SW_DEV
6092 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6093#endif
6094#ifdef _SC_2_UPE
6095 {"SC_2_UPE", _SC_2_UPE},
6096#endif
6097#ifdef _SC_2_VERSION
6098 {"SC_2_VERSION", _SC_2_VERSION},
6099#endif
Fred Draked86ed291999-12-15 15:34:33 +00006100#ifdef _SC_ABI_ASYNCHRONOUS_IO
6101 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6102#endif
6103#ifdef _SC_ACL
6104 {"SC_ACL", _SC_ACL},
6105#endif
Fred Drakec9680921999-12-13 16:37:25 +00006106#ifdef _SC_AIO_LISTIO_MAX
6107 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6108#endif
Fred Drakec9680921999-12-13 16:37:25 +00006109#ifdef _SC_AIO_MAX
6110 {"SC_AIO_MAX", _SC_AIO_MAX},
6111#endif
6112#ifdef _SC_AIO_PRIO_DELTA_MAX
6113 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6114#endif
6115#ifdef _SC_ARG_MAX
6116 {"SC_ARG_MAX", _SC_ARG_MAX},
6117#endif
6118#ifdef _SC_ASYNCHRONOUS_IO
6119 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6120#endif
6121#ifdef _SC_ATEXIT_MAX
6122 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6123#endif
Fred Draked86ed291999-12-15 15:34:33 +00006124#ifdef _SC_AUDIT
6125 {"SC_AUDIT", _SC_AUDIT},
6126#endif
Fred Drakec9680921999-12-13 16:37:25 +00006127#ifdef _SC_AVPHYS_PAGES
6128 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6129#endif
6130#ifdef _SC_BC_BASE_MAX
6131 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6132#endif
6133#ifdef _SC_BC_DIM_MAX
6134 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6135#endif
6136#ifdef _SC_BC_SCALE_MAX
6137 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6138#endif
6139#ifdef _SC_BC_STRING_MAX
6140 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6141#endif
Fred Draked86ed291999-12-15 15:34:33 +00006142#ifdef _SC_CAP
6143 {"SC_CAP", _SC_CAP},
6144#endif
Fred Drakec9680921999-12-13 16:37:25 +00006145#ifdef _SC_CHARCLASS_NAME_MAX
6146 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6147#endif
6148#ifdef _SC_CHAR_BIT
6149 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6150#endif
6151#ifdef _SC_CHAR_MAX
6152 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6153#endif
6154#ifdef _SC_CHAR_MIN
6155 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6156#endif
6157#ifdef _SC_CHILD_MAX
6158 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6159#endif
6160#ifdef _SC_CLK_TCK
6161 {"SC_CLK_TCK", _SC_CLK_TCK},
6162#endif
6163#ifdef _SC_COHER_BLKSZ
6164 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6165#endif
6166#ifdef _SC_COLL_WEIGHTS_MAX
6167 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6168#endif
6169#ifdef _SC_DCACHE_ASSOC
6170 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6171#endif
6172#ifdef _SC_DCACHE_BLKSZ
6173 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6174#endif
6175#ifdef _SC_DCACHE_LINESZ
6176 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6177#endif
6178#ifdef _SC_DCACHE_SZ
6179 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6180#endif
6181#ifdef _SC_DCACHE_TBLKSZ
6182 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6183#endif
6184#ifdef _SC_DELAYTIMER_MAX
6185 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6186#endif
6187#ifdef _SC_EQUIV_CLASS_MAX
6188 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6189#endif
6190#ifdef _SC_EXPR_NEST_MAX
6191 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6192#endif
6193#ifdef _SC_FSYNC
6194 {"SC_FSYNC", _SC_FSYNC},
6195#endif
6196#ifdef _SC_GETGR_R_SIZE_MAX
6197 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6198#endif
6199#ifdef _SC_GETPW_R_SIZE_MAX
6200 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6201#endif
6202#ifdef _SC_ICACHE_ASSOC
6203 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6204#endif
6205#ifdef _SC_ICACHE_BLKSZ
6206 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6207#endif
6208#ifdef _SC_ICACHE_LINESZ
6209 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6210#endif
6211#ifdef _SC_ICACHE_SZ
6212 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6213#endif
Fred Draked86ed291999-12-15 15:34:33 +00006214#ifdef _SC_INF
6215 {"SC_INF", _SC_INF},
6216#endif
Fred Drakec9680921999-12-13 16:37:25 +00006217#ifdef _SC_INT_MAX
6218 {"SC_INT_MAX", _SC_INT_MAX},
6219#endif
6220#ifdef _SC_INT_MIN
6221 {"SC_INT_MIN", _SC_INT_MIN},
6222#endif
6223#ifdef _SC_IOV_MAX
6224 {"SC_IOV_MAX", _SC_IOV_MAX},
6225#endif
Fred Draked86ed291999-12-15 15:34:33 +00006226#ifdef _SC_IP_SECOPTS
6227 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6228#endif
Fred Drakec9680921999-12-13 16:37:25 +00006229#ifdef _SC_JOB_CONTROL
6230 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6231#endif
Fred Draked86ed291999-12-15 15:34:33 +00006232#ifdef _SC_KERN_POINTERS
6233 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6234#endif
6235#ifdef _SC_KERN_SIM
6236 {"SC_KERN_SIM", _SC_KERN_SIM},
6237#endif
Fred Drakec9680921999-12-13 16:37:25 +00006238#ifdef _SC_LINE_MAX
6239 {"SC_LINE_MAX", _SC_LINE_MAX},
6240#endif
6241#ifdef _SC_LOGIN_NAME_MAX
6242 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6243#endif
6244#ifdef _SC_LOGNAME_MAX
6245 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6246#endif
6247#ifdef _SC_LONG_BIT
6248 {"SC_LONG_BIT", _SC_LONG_BIT},
6249#endif
Fred Draked86ed291999-12-15 15:34:33 +00006250#ifdef _SC_MAC
6251 {"SC_MAC", _SC_MAC},
6252#endif
Fred Drakec9680921999-12-13 16:37:25 +00006253#ifdef _SC_MAPPED_FILES
6254 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6255#endif
6256#ifdef _SC_MAXPID
6257 {"SC_MAXPID", _SC_MAXPID},
6258#endif
6259#ifdef _SC_MB_LEN_MAX
6260 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6261#endif
6262#ifdef _SC_MEMLOCK
6263 {"SC_MEMLOCK", _SC_MEMLOCK},
6264#endif
6265#ifdef _SC_MEMLOCK_RANGE
6266 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6267#endif
6268#ifdef _SC_MEMORY_PROTECTION
6269 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6270#endif
6271#ifdef _SC_MESSAGE_PASSING
6272 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6273#endif
Fred Draked86ed291999-12-15 15:34:33 +00006274#ifdef _SC_MMAP_FIXED_ALIGNMENT
6275 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6276#endif
Fred Drakec9680921999-12-13 16:37:25 +00006277#ifdef _SC_MQ_OPEN_MAX
6278 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6279#endif
6280#ifdef _SC_MQ_PRIO_MAX
6281 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6282#endif
Fred Draked86ed291999-12-15 15:34:33 +00006283#ifdef _SC_NACLS_MAX
6284 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6285#endif
Fred Drakec9680921999-12-13 16:37:25 +00006286#ifdef _SC_NGROUPS_MAX
6287 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6288#endif
6289#ifdef _SC_NL_ARGMAX
6290 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6291#endif
6292#ifdef _SC_NL_LANGMAX
6293 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6294#endif
6295#ifdef _SC_NL_MSGMAX
6296 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6297#endif
6298#ifdef _SC_NL_NMAX
6299 {"SC_NL_NMAX", _SC_NL_NMAX},
6300#endif
6301#ifdef _SC_NL_SETMAX
6302 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6303#endif
6304#ifdef _SC_NL_TEXTMAX
6305 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6306#endif
6307#ifdef _SC_NPROCESSORS_CONF
6308 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6309#endif
6310#ifdef _SC_NPROCESSORS_ONLN
6311 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6312#endif
Fred Draked86ed291999-12-15 15:34:33 +00006313#ifdef _SC_NPROC_CONF
6314 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6315#endif
6316#ifdef _SC_NPROC_ONLN
6317 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6318#endif
Fred Drakec9680921999-12-13 16:37:25 +00006319#ifdef _SC_NZERO
6320 {"SC_NZERO", _SC_NZERO},
6321#endif
6322#ifdef _SC_OPEN_MAX
6323 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6324#endif
6325#ifdef _SC_PAGESIZE
6326 {"SC_PAGESIZE", _SC_PAGESIZE},
6327#endif
6328#ifdef _SC_PAGE_SIZE
6329 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6330#endif
6331#ifdef _SC_PASS_MAX
6332 {"SC_PASS_MAX", _SC_PASS_MAX},
6333#endif
6334#ifdef _SC_PHYS_PAGES
6335 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6336#endif
6337#ifdef _SC_PII
6338 {"SC_PII", _SC_PII},
6339#endif
6340#ifdef _SC_PII_INTERNET
6341 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6342#endif
6343#ifdef _SC_PII_INTERNET_DGRAM
6344 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6345#endif
6346#ifdef _SC_PII_INTERNET_STREAM
6347 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6348#endif
6349#ifdef _SC_PII_OSI
6350 {"SC_PII_OSI", _SC_PII_OSI},
6351#endif
6352#ifdef _SC_PII_OSI_CLTS
6353 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6354#endif
6355#ifdef _SC_PII_OSI_COTS
6356 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6357#endif
6358#ifdef _SC_PII_OSI_M
6359 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6360#endif
6361#ifdef _SC_PII_SOCKET
6362 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6363#endif
6364#ifdef _SC_PII_XTI
6365 {"SC_PII_XTI", _SC_PII_XTI},
6366#endif
6367#ifdef _SC_POLL
6368 {"SC_POLL", _SC_POLL},
6369#endif
6370#ifdef _SC_PRIORITIZED_IO
6371 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6372#endif
6373#ifdef _SC_PRIORITY_SCHEDULING
6374 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6375#endif
6376#ifdef _SC_REALTIME_SIGNALS
6377 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6378#endif
6379#ifdef _SC_RE_DUP_MAX
6380 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6381#endif
6382#ifdef _SC_RTSIG_MAX
6383 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6384#endif
6385#ifdef _SC_SAVED_IDS
6386 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6387#endif
6388#ifdef _SC_SCHAR_MAX
6389 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6390#endif
6391#ifdef _SC_SCHAR_MIN
6392 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6393#endif
6394#ifdef _SC_SELECT
6395 {"SC_SELECT", _SC_SELECT},
6396#endif
6397#ifdef _SC_SEMAPHORES
6398 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6399#endif
6400#ifdef _SC_SEM_NSEMS_MAX
6401 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6402#endif
6403#ifdef _SC_SEM_VALUE_MAX
6404 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6405#endif
6406#ifdef _SC_SHARED_MEMORY_OBJECTS
6407 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6408#endif
6409#ifdef _SC_SHRT_MAX
6410 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6411#endif
6412#ifdef _SC_SHRT_MIN
6413 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6414#endif
6415#ifdef _SC_SIGQUEUE_MAX
6416 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6417#endif
6418#ifdef _SC_SIGRT_MAX
6419 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6420#endif
6421#ifdef _SC_SIGRT_MIN
6422 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6423#endif
Fred Draked86ed291999-12-15 15:34:33 +00006424#ifdef _SC_SOFTPOWER
6425 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6426#endif
Fred Drakec9680921999-12-13 16:37:25 +00006427#ifdef _SC_SPLIT_CACHE
6428 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6429#endif
6430#ifdef _SC_SSIZE_MAX
6431 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6432#endif
6433#ifdef _SC_STACK_PROT
6434 {"SC_STACK_PROT", _SC_STACK_PROT},
6435#endif
6436#ifdef _SC_STREAM_MAX
6437 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6438#endif
6439#ifdef _SC_SYNCHRONIZED_IO
6440 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6441#endif
6442#ifdef _SC_THREADS
6443 {"SC_THREADS", _SC_THREADS},
6444#endif
6445#ifdef _SC_THREAD_ATTR_STACKADDR
6446 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6447#endif
6448#ifdef _SC_THREAD_ATTR_STACKSIZE
6449 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6450#endif
6451#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6452 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6453#endif
6454#ifdef _SC_THREAD_KEYS_MAX
6455 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6456#endif
6457#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6458 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6459#endif
6460#ifdef _SC_THREAD_PRIO_INHERIT
6461 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6462#endif
6463#ifdef _SC_THREAD_PRIO_PROTECT
6464 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6465#endif
6466#ifdef _SC_THREAD_PROCESS_SHARED
6467 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6468#endif
6469#ifdef _SC_THREAD_SAFE_FUNCTIONS
6470 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6471#endif
6472#ifdef _SC_THREAD_STACK_MIN
6473 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6474#endif
6475#ifdef _SC_THREAD_THREADS_MAX
6476 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6477#endif
6478#ifdef _SC_TIMERS
6479 {"SC_TIMERS", _SC_TIMERS},
6480#endif
6481#ifdef _SC_TIMER_MAX
6482 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6483#endif
6484#ifdef _SC_TTY_NAME_MAX
6485 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6486#endif
6487#ifdef _SC_TZNAME_MAX
6488 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6489#endif
6490#ifdef _SC_T_IOV_MAX
6491 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6492#endif
6493#ifdef _SC_UCHAR_MAX
6494 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6495#endif
6496#ifdef _SC_UINT_MAX
6497 {"SC_UINT_MAX", _SC_UINT_MAX},
6498#endif
6499#ifdef _SC_UIO_MAXIOV
6500 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6501#endif
6502#ifdef _SC_ULONG_MAX
6503 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6504#endif
6505#ifdef _SC_USHRT_MAX
6506 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6507#endif
6508#ifdef _SC_VERSION
6509 {"SC_VERSION", _SC_VERSION},
6510#endif
6511#ifdef _SC_WORD_BIT
6512 {"SC_WORD_BIT", _SC_WORD_BIT},
6513#endif
6514#ifdef _SC_XBS5_ILP32_OFF32
6515 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6516#endif
6517#ifdef _SC_XBS5_ILP32_OFFBIG
6518 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6519#endif
6520#ifdef _SC_XBS5_LP64_OFF64
6521 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6522#endif
6523#ifdef _SC_XBS5_LPBIG_OFFBIG
6524 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6525#endif
6526#ifdef _SC_XOPEN_CRYPT
6527 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6528#endif
6529#ifdef _SC_XOPEN_ENH_I18N
6530 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6531#endif
6532#ifdef _SC_XOPEN_LEGACY
6533 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6534#endif
6535#ifdef _SC_XOPEN_REALTIME
6536 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6537#endif
6538#ifdef _SC_XOPEN_REALTIME_THREADS
6539 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6540#endif
6541#ifdef _SC_XOPEN_SHM
6542 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6543#endif
6544#ifdef _SC_XOPEN_UNIX
6545 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6546#endif
6547#ifdef _SC_XOPEN_VERSION
6548 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6549#endif
6550#ifdef _SC_XOPEN_XCU_VERSION
6551 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6552#endif
6553#ifdef _SC_XOPEN_XPG2
6554 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6555#endif
6556#ifdef _SC_XOPEN_XPG3
6557 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6558#endif
6559#ifdef _SC_XOPEN_XPG4
6560 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6561#endif
6562};
6563
6564static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006565conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006566{
6567 return conv_confname(arg, valuep, posix_constants_sysconf,
6568 sizeof(posix_constants_sysconf)
6569 / sizeof(struct constdef));
6570}
6571
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006572PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006573"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006574Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006575
6576static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006577posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006578{
6579 PyObject *result = NULL;
6580 int name;
6581
6582 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6583 int value;
6584
6585 errno = 0;
6586 value = sysconf(name);
6587 if (value == -1 && errno != 0)
6588 posix_error();
6589 else
6590 result = PyInt_FromLong(value);
6591 }
6592 return result;
6593}
6594#endif
6595
6596
Fred Drakebec628d1999-12-15 18:31:10 +00006597/* This code is used to ensure that the tables of configuration value names
6598 * are in sorted order as required by conv_confname(), and also to build the
6599 * the exported dictionaries that are used to publish information about the
6600 * names available on the host platform.
6601 *
6602 * Sorting the table at runtime ensures that the table is properly ordered
6603 * when used, even for platforms we're not able to test on. It also makes
6604 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006605 */
Fred Drakebec628d1999-12-15 18:31:10 +00006606
6607static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006608cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006609{
6610 const struct constdef *c1 =
6611 (const struct constdef *) v1;
6612 const struct constdef *c2 =
6613 (const struct constdef *) v2;
6614
6615 return strcmp(c1->name, c2->name);
6616}
6617
6618static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006619setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006620 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006621{
Fred Drakebec628d1999-12-15 18:31:10 +00006622 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006623 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006624
6625 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6626 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006627 if (d == NULL)
6628 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006629
Barry Warsaw3155db32000-04-13 15:20:40 +00006630 for (i=0; i < tablesize; ++i) {
6631 PyObject *o = PyInt_FromLong(table[i].value);
6632 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6633 Py_XDECREF(o);
6634 Py_DECREF(d);
6635 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006636 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006637 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006638 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006639 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006640}
6641
Fred Drakebec628d1999-12-15 18:31:10 +00006642/* Return -1 on failure, 0 on success. */
6643static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006644setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006645{
6646#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006647 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006648 sizeof(posix_constants_pathconf)
6649 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006650 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006651 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006652#endif
6653#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006654 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006655 sizeof(posix_constants_confstr)
6656 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006657 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006658 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006659#endif
6660#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006661 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006662 sizeof(posix_constants_sysconf)
6663 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006664 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006665 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006666#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006667 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006668}
Fred Draked86ed291999-12-15 15:34:33 +00006669
6670
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006671PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006672"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006673Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006674in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006675
6676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006677posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006678{
6679 if (!PyArg_ParseTuple(args, ":abort"))
6680 return NULL;
6681 abort();
6682 /*NOTREACHED*/
6683 Py_FatalError("abort() called from Python code didn't abort!");
6684 return NULL;
6685}
Fred Drakebec628d1999-12-15 18:31:10 +00006686
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006687#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006688PyDoc_STRVAR(win32_startfile__doc__,
6689"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006690\n\
6691This acts like double-clicking the file in Explorer, or giving the file\n\
6692name as an argument to the DOS \"start\" command: the file is opened\n\
6693with whatever application (if any) its extension is associated.\n\
6694\n\
6695startfile returns as soon as the associated application is launched.\n\
6696There is no option to wait for the application to close, and no way\n\
6697to retrieve the application's exit status.\n\
6698\n\
6699The filepath is relative to the current directory. If you want to use\n\
6700an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006701the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006702
6703static PyObject *
6704win32_startfile(PyObject *self, PyObject *args)
6705{
6706 char *filepath;
6707 HINSTANCE rc;
6708 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6709 return NULL;
6710 Py_BEGIN_ALLOW_THREADS
6711 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6712 Py_END_ALLOW_THREADS
6713 if (rc <= (HINSTANCE)32)
6714 return win32_error("startfile", filepath);
6715 Py_INCREF(Py_None);
6716 return Py_None;
6717}
6718#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006719
6720static PyMethodDef posix_methods[] = {
6721 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6722#ifdef HAVE_TTYNAME
6723 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6724#endif
6725 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6726 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006727#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006728 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006729#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006730#ifdef HAVE_LCHOWN
6731 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6732#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006733#ifdef HAVE_CHROOT
6734 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6735#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006736#ifdef HAVE_CTERMID
6737 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6738#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006739#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006740 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006741 {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006742#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006743#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006744 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006745#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006746 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6747 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6748 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006749#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006750 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006751#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006752#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006753 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006754#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006755 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6756 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6757 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006758#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006759 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006760#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006761#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006762 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006763#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006764 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006765#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006766 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006767#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006768 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6769 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6770 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006771#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006772 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006773#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006774 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006775#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006776 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6777 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006778#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006779#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006780 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6781 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006782#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006783#ifdef HAVE_FORK1
6784 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6785#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006786#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006787 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006788#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006789#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006790 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006791#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006792#ifdef HAVE_FORKPTY
6793 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6794#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006795#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006796 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006797#endif /* HAVE_GETEGID */
6798#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006799 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006800#endif /* HAVE_GETEUID */
6801#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006802 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006803#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006804#ifdef HAVE_GETGROUPS
6805 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6806#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006807 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006808#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006809 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006810#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006811#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006812 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006813#endif /* HAVE_GETPPID */
6814#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006815 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006816#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006817#ifdef HAVE_GETLOGIN
6818 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6819#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006820#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006821 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006822#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006823#ifdef HAVE_KILLPG
6824 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6825#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006826#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006827 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006828#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006829#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006830 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006831#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006832 {"popen2", win32_popen2, METH_VARARGS},
6833 {"popen3", win32_popen3, METH_VARARGS},
6834 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006835 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006836#else
6837#if defined(PYOS_OS2) && defined(PYCC_GCC)
6838 {"popen2", os2emx_popen2, METH_VARARGS},
6839 {"popen3", os2emx_popen3, METH_VARARGS},
6840 {"popen4", os2emx_popen4, METH_VARARGS},
6841#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006842#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006843#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006844#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006845 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006846#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006847#ifdef HAVE_SETEUID
6848 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6849#endif /* HAVE_SETEUID */
6850#ifdef HAVE_SETEGID
6851 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6852#endif /* HAVE_SETEGID */
6853#ifdef HAVE_SETREUID
6854 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6855#endif /* HAVE_SETREUID */
6856#ifdef HAVE_SETREGID
6857 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6858#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006859#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006860 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006861#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006862#ifdef HAVE_SETGROUPS
6863 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6864#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006865#ifdef HAVE_GETPGID
6866 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6867#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006868#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006869 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006870#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006871#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006872 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006873#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006874#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006875 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006876#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006877#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006878 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006879#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006880#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006881 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006882#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006883#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006884 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006885#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006886#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006887 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006888#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006889 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6890 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6891 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6892 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6893 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6894 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6895 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6896 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6897 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006898 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006899#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006900 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006901#endif
6902#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006903 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006904#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006905#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006906 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6907#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006908#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006909 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006910#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006911#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006912 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006913#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006914#ifdef HAVE_UNSETENV
6915 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6916#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006917#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006918 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006919#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006920#ifdef HAVE_FCHDIR
6921 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6922#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006923#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006924 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006925#endif
6926#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006927 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006928#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006929#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006930#ifdef WCOREDUMP
6931 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6932#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006933#ifdef WIFCONTINUED
6934 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6935#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006936#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006937 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006938#endif /* WIFSTOPPED */
6939#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006940 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006941#endif /* WIFSIGNALED */
6942#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006943 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006944#endif /* WIFEXITED */
6945#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006946 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006947#endif /* WEXITSTATUS */
6948#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006949 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006950#endif /* WTERMSIG */
6951#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006952 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006953#endif /* WSTOPSIG */
6954#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006955#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006956 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006957#endif
6958#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006959 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006960#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006961#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006962 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6963#endif
6964#ifdef HAVE_TEMPNAM
6965 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6966#endif
6967#ifdef HAVE_TMPNAM
6968 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6969#endif
Fred Drakec9680921999-12-13 16:37:25 +00006970#ifdef HAVE_CONFSTR
6971 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6972#endif
6973#ifdef HAVE_SYSCONF
6974 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6975#endif
6976#ifdef HAVE_FPATHCONF
6977 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6978#endif
6979#ifdef HAVE_PATHCONF
6980 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6981#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006982 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006983#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006984 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6985#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006986 {NULL, NULL} /* Sentinel */
6987};
6988
6989
Barry Warsaw4a342091996-12-19 23:50:02 +00006990static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006991ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006992{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006993 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006994}
6995
Guido van Rossumd48f2521997-12-05 22:19:34 +00006996#if defined(PYOS_OS2)
6997/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006998static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006999{
7000 APIRET rc;
7001 ULONG values[QSV_MAX+1];
7002 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007003 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007004
7005 Py_BEGIN_ALLOW_THREADS
7006 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7007 Py_END_ALLOW_THREADS
7008
7009 if (rc != NO_ERROR) {
7010 os2_error(rc);
7011 return -1;
7012 }
7013
Fred Drake4d1e64b2002-04-15 19:40:07 +00007014 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7015 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7016 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7017 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7018 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7019 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7020 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007021
7022 switch (values[QSV_VERSION_MINOR]) {
7023 case 0: ver = "2.00"; break;
7024 case 10: ver = "2.10"; break;
7025 case 11: ver = "2.11"; break;
7026 case 30: ver = "3.00"; break;
7027 case 40: ver = "4.00"; break;
7028 case 50: ver = "5.00"; break;
7029 default:
Tim Peters885d4572001-11-28 20:27:42 +00007030 PyOS_snprintf(tmp, sizeof(tmp),
7031 "%d-%d", values[QSV_VERSION_MAJOR],
7032 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007033 ver = &tmp[0];
7034 }
7035
7036 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007037 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007038 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007039
7040 /* Add Indicator of Which Drive was Used to Boot the System */
7041 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7042 tmp[1] = ':';
7043 tmp[2] = '\0';
7044
Fred Drake4d1e64b2002-04-15 19:40:07 +00007045 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007046}
7047#endif
7048
Barry Warsaw4a342091996-12-19 23:50:02 +00007049static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007050all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007051{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007052#ifdef F_OK
7053 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007054#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007055#ifdef R_OK
7056 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007057#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007058#ifdef W_OK
7059 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007060#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007061#ifdef X_OK
7062 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007063#endif
Fred Drakec9680921999-12-13 16:37:25 +00007064#ifdef NGROUPS_MAX
7065 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7066#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007067#ifdef TMP_MAX
7068 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7069#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007070#ifdef WCONTINUED
7071 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7072#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007073#ifdef WNOHANG
7074 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007075#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007076#ifdef WUNTRACED
7077 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7078#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007079#ifdef O_RDONLY
7080 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7081#endif
7082#ifdef O_WRONLY
7083 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7084#endif
7085#ifdef O_RDWR
7086 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7087#endif
7088#ifdef O_NDELAY
7089 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7090#endif
7091#ifdef O_NONBLOCK
7092 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7093#endif
7094#ifdef O_APPEND
7095 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7096#endif
7097#ifdef O_DSYNC
7098 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7099#endif
7100#ifdef O_RSYNC
7101 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7102#endif
7103#ifdef O_SYNC
7104 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7105#endif
7106#ifdef O_NOCTTY
7107 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7108#endif
7109#ifdef O_CREAT
7110 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7111#endif
7112#ifdef O_EXCL
7113 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7114#endif
7115#ifdef O_TRUNC
7116 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7117#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007118#ifdef O_BINARY
7119 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7120#endif
7121#ifdef O_TEXT
7122 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7123#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007124#ifdef O_LARGEFILE
7125 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7126#endif
7127
Tim Peters5aa91602002-01-30 05:46:57 +00007128/* MS Windows */
7129#ifdef O_NOINHERIT
7130 /* Don't inherit in child processes. */
7131 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7132#endif
7133#ifdef _O_SHORT_LIVED
7134 /* Optimize for short life (keep in memory). */
7135 /* MS forgot to define this one with a non-underscore form too. */
7136 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7137#endif
7138#ifdef O_TEMPORARY
7139 /* Automatically delete when last handle is closed. */
7140 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7141#endif
7142#ifdef O_RANDOM
7143 /* Optimize for random access. */
7144 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7145#endif
7146#ifdef O_SEQUENTIAL
7147 /* Optimize for sequential access. */
7148 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7149#endif
7150
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007151/* GNU extensions. */
7152#ifdef O_DIRECT
7153 /* Direct disk access. */
7154 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7155#endif
7156#ifdef O_DIRECTORY
7157 /* Must be a directory. */
7158 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7159#endif
7160#ifdef O_NOFOLLOW
7161 /* Do not follow links. */
7162 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7163#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007164
Guido van Rossum246bc171999-02-01 23:54:31 +00007165#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007166#if defined(PYOS_OS2) && defined(PYCC_GCC)
7167 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7168 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7169 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7170 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7171 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7172 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7173 if (ins(d, "P_PM", (long)P_PM)) return -1;
7174 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7175 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7176 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7177 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7178 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7179 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7180 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7181 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7182 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7183 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7184 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7185 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7186 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7187#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007188 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7189 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7190 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7191 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7192 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007193#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007194#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007195
Guido van Rossumd48f2521997-12-05 22:19:34 +00007196#if defined(PYOS_OS2)
7197 if (insertvalues(d)) return -1;
7198#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007199 return 0;
7200}
7201
7202
Tim Peters5aa91602002-01-30 05:46:57 +00007203#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007204#define INITFUNC initnt
7205#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007206
7207#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007208#define INITFUNC initos2
7209#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007210
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007211#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007212#define INITFUNC initposix
7213#define MODNAME "posix"
7214#endif
7215
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007216PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007217INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007218{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007219 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007220
Fred Drake4d1e64b2002-04-15 19:40:07 +00007221 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007222 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007223 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007224
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007225 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007226 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007227 Py_XINCREF(v);
7228 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007229 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007230 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007231
Fred Drake4d1e64b2002-04-15 19:40:07 +00007232 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007233 return;
7234
Fred Drake4d1e64b2002-04-15 19:40:07 +00007235 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007236 return;
7237
Fred Drake4d1e64b2002-04-15 19:40:07 +00007238 Py_INCREF(PyExc_OSError);
7239 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007240
Guido van Rossumb3d39562000-01-31 18:41:26 +00007241#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007242 if (posix_putenv_garbage == NULL)
7243 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007244#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007245
Guido van Rossum14648392001-12-08 18:02:58 +00007246 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007247 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007248 Py_INCREF((PyObject*) &StatResultType);
7249 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007250
Guido van Rossum14648392001-12-08 18:02:58 +00007251 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007252 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007253 Py_INCREF((PyObject*) &StatVFSResultType);
7254 PyModule_AddObject(m, "statvfs_result",
7255 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007256}