blob: c611b0722bca0a3c4bc733a1c35bc4cb81f4aff0 [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
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000280#if defined(MAJOR_IN_MKDEV)
281#include <sys/mkdev.h>
282#else
283#if defined(MAJOR_IN_SYSMACROS)
284#include <sys/sysmacros.h>
285#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000286#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
287#include <sys/mkdev.h>
288#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000289#endif
Fred Drake699f3522000-06-29 21:12:41 +0000290
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000292#ifdef WITH_NEXT_FRAMEWORK
293/* On Darwin/MacOSX a shared library or framework has no access to
294** environ directly, we must obtain it with _NSGetEnviron().
295*/
296#include <crt_externs.h>
297static char **environ;
298#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000300#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301
Barry Warsaw53699e91996-12-10 23:23:01 +0000302static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000303convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304{
Barry Warsaw53699e91996-12-10 23:23:01 +0000305 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000307 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308 if (d == NULL)
309 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000310#ifdef WITH_NEXT_FRAMEWORK
311 if (environ == NULL)
312 environ = *_NSGetEnviron();
313#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000314 if (environ == NULL)
315 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000316 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000318 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000319 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000320 char *p = strchr(*e, '=');
321 if (p == NULL)
322 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000323 k = PyString_FromStringAndSize(*e, (int)(p-*e));
324 if (k == NULL) {
325 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000326 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000327 }
328 v = PyString_FromString(p+1);
329 if (v == NULL) {
330 PyErr_Clear();
331 Py_DECREF(k);
332 continue;
333 }
334 if (PyDict_GetItem(d, k) == NULL) {
335 if (PyDict_SetItem(d, k, v) != 0)
336 PyErr_Clear();
337 }
338 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000339 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000340 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000341#if defined(PYOS_OS2)
342 {
343 APIRET rc;
344 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
345
346 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000347 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000348 PyObject *v = PyString_FromString(buffer);
349 PyDict_SetItemString(d, "BEGINLIBPATH", v);
350 Py_DECREF(v);
351 }
352 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
353 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
354 PyObject *v = PyString_FromString(buffer);
355 PyDict_SetItemString(d, "ENDLIBPATH", v);
356 Py_DECREF(v);
357 }
358 }
359#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000360 return d;
361}
362
363
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000364/* Set a POSIX-specific error from errno, and return NULL */
365
Barry Warsawd58d7641998-07-23 16:14:40 +0000366static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000367posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000368{
Barry Warsawca74da41999-02-09 19:31:45 +0000369 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000370}
Barry Warsawd58d7641998-07-23 16:14:40 +0000371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000372posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000373{
Barry Warsawca74da41999-02-09 19:31:45 +0000374 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000375}
376
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000377#ifdef Py_WIN_WIDE_FILENAMES
378static PyObject *
379posix_error_with_unicode_filename(Py_UNICODE* name)
380{
381 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
382}
383#endif /* Py_WIN_WIDE_FILENAMES */
384
385
Mark Hammondef8b6542001-05-13 08:04:26 +0000386static PyObject *
387posix_error_with_allocated_filename(char* name)
388{
389 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
390 PyMem_Free(name);
391 return rc;
392}
393
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000394#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000395static PyObject *
396win32_error(char* function, char* filename)
397{
Mark Hammond33a6da92000-08-15 00:46:38 +0000398 /* XXX We should pass the function name along in the future.
399 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000400 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000401 Windows error object, which is non-trivial.
402 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000403 errno = GetLastError();
404 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000405 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000406 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000407 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000408}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000409
410#ifdef Py_WIN_WIDE_FILENAMES
411static PyObject *
412win32_error_unicode(char* function, Py_UNICODE* filename)
413{
414 /* XXX - see win32_error for comments on 'function' */
415 errno = GetLastError();
416 if (filename)
417 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
418 else
419 return PyErr_SetFromWindowsErr(errno);
420}
421
422static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
423{
424 /* XXX Perhaps we should make this API an alias of
425 PyObject_Unicode() instead ?! */
426 if (PyUnicode_CheckExact(obj)) {
427 Py_INCREF(obj);
428 return obj;
429 }
430 if (PyUnicode_Check(obj)) {
431 /* For a Unicode subtype that's not a Unicode object,
432 return a true Unicode object with the same data. */
433 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
434 PyUnicode_GET_SIZE(obj));
435 }
436 return PyUnicode_FromEncodedObject(obj,
437 Py_FileSystemDefaultEncoding,
438 "strict");
439}
440
441#endif /* Py_WIN_WIDE_FILENAMES */
442
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000443#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444
Guido van Rossumd48f2521997-12-05 22:19:34 +0000445#if defined(PYOS_OS2)
446/**********************************************************************
447 * Helper Function to Trim and Format OS/2 Messages
448 **********************************************************************/
449 static void
450os2_formatmsg(char *msgbuf, int msglen, char *reason)
451{
452 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
453
454 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
455 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
456
457 while (lastc > msgbuf && isspace(*lastc))
458 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
459 }
460
461 /* Add Optional Reason Text */
462 if (reason) {
463 strcat(msgbuf, " : ");
464 strcat(msgbuf, reason);
465 }
466}
467
468/**********************************************************************
469 * Decode an OS/2 Operating System Error Code
470 *
471 * A convenience function to lookup an OS/2 error code and return a
472 * text message we can use to raise a Python exception.
473 *
474 * Notes:
475 * The messages for errors returned from the OS/2 kernel reside in
476 * the file OSO001.MSG in the \OS2 directory hierarchy.
477 *
478 **********************************************************************/
479 static char *
480os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
481{
482 APIRET rc;
483 ULONG msglen;
484
485 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
486 Py_BEGIN_ALLOW_THREADS
487 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
488 errorcode, "oso001.msg", &msglen);
489 Py_END_ALLOW_THREADS
490
491 if (rc == NO_ERROR)
492 os2_formatmsg(msgbuf, msglen, reason);
493 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000494 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000495 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000496
497 return msgbuf;
498}
499
500/* Set an OS/2-specific error and return NULL. OS/2 kernel
501 errors are not in a global variable e.g. 'errno' nor are
502 they congruent with posix error numbers. */
503
504static PyObject * os2_error(int code)
505{
506 char text[1024];
507 PyObject *v;
508
509 os2_strerror(text, sizeof(text), code, "");
510
511 v = Py_BuildValue("(is)", code, text);
512 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000513 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000514 Py_DECREF(v);
515 }
516 return NULL; /* Signal to Python that an Exception is Pending */
517}
518
519#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000520
521/* POSIX generic methods */
522
Barry Warsaw53699e91996-12-10 23:23:01 +0000523static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000524posix_fildes(PyObject *fdobj, int (*func)(int))
525{
526 int fd;
527 int res;
528 fd = PyObject_AsFileDescriptor(fdobj);
529 if (fd < 0)
530 return NULL;
531 Py_BEGIN_ALLOW_THREADS
532 res = (*func)(fd);
533 Py_END_ALLOW_THREADS
534 if (res < 0)
535 return posix_error();
536 Py_INCREF(Py_None);
537 return Py_None;
538}
Guido van Rossum21142a01999-01-08 21:05:37 +0000539
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000540#ifdef Py_WIN_WIDE_FILENAMES
541static int
542unicode_file_names(void)
543{
544 static int canusewide = -1;
545 if (canusewide == -1) {
546 /* As per doc for ::GetVersion(), this is the correct test for
547 the Windows NT family. */
548 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
549 }
550 return canusewide;
551}
552#endif
553
Guido van Rossum21142a01999-01-08 21:05:37 +0000554static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000555posix_1str(PyObject *args, char *format, int (*func)(const char*),
556 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000557{
Mark Hammondef8b6542001-05-13 08:04:26 +0000558 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000559 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000560#ifdef Py_WIN_WIDE_FILENAMES
561 if (unicode_file_names()) {
562 PyUnicodeObject *po;
563 if (PyArg_ParseTuple(args, wformat, &po)) {
564 Py_BEGIN_ALLOW_THREADS
565 /* PyUnicode_AS_UNICODE OK without thread
566 lock as it is a simple dereference. */
567 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
568 Py_END_ALLOW_THREADS
569 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000570 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000571 Py_INCREF(Py_None);
572 return Py_None;
573 }
574 /* Drop the argument parsing error as narrow
575 strings are also valid. */
576 PyErr_Clear();
577 }
578#else
579 /* Platforms that don't support Unicode filenames
580 shouldn't be passing these extra params */
581 assert(wformat==NULL && wfunc == NULL);
582#endif
583
Tim Peters5aa91602002-01-30 05:46:57 +0000584 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000585 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000586 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000587 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000588 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000589 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000590 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000591 return posix_error_with_allocated_filename(path1);
592 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000593 Py_INCREF(Py_None);
594 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000595}
596
Barry Warsaw53699e91996-12-10 23:23:01 +0000597static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000598posix_2str(PyObject *args,
599 char *format,
600 int (*func)(const char *, const char *),
601 char *wformat,
602 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603{
Mark Hammondef8b6542001-05-13 08:04:26 +0000604 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000605 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000606#ifdef Py_WIN_WIDE_FILENAMES
607 if (unicode_file_names()) {
608 PyObject *po1;
609 PyObject *po2;
610 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
611 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
612 PyObject *wpath1;
613 PyObject *wpath2;
614 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
615 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
616 if (!wpath1 || !wpath2) {
617 Py_XDECREF(wpath1);
618 Py_XDECREF(wpath2);
619 return NULL;
620 }
621 Py_BEGIN_ALLOW_THREADS
622 /* PyUnicode_AS_UNICODE OK without thread
623 lock as it is a simple dereference. */
624 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
625 PyUnicode_AS_UNICODE(wpath2));
626 Py_END_ALLOW_THREADS
627 Py_XDECREF(wpath1);
628 Py_XDECREF(wpath2);
629 if (res != 0)
630 return posix_error();
631 Py_INCREF(Py_None);
632 return Py_None;
633 }
634 /* Else flow through as neither is Unicode. */
635 }
636 /* Drop the argument parsing error as narrow
637 strings are also valid. */
638 PyErr_Clear();
639 }
640#else
641 /* Platforms that don't support Unicode filenames
642 shouldn't be passing these extra params */
643 assert(wformat==NULL && wfunc == NULL);
644#endif
645
Mark Hammondef8b6542001-05-13 08:04:26 +0000646 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000647 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000648 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000649 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000650 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000651 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000652 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000653 PyMem_Free(path1);
654 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000655 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000656 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000657 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000658 Py_INCREF(Py_None);
659 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000660}
661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000662PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000663"stat_result: Result from stat or lstat.\n\n\
664This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000665 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000666or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
667\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000668Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000669they are available as attributes only.\n\
670\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000671See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000672
673static PyStructSequence_Field stat_result_fields[] = {
674 {"st_mode", "protection bits"},
675 {"st_ino", "inode"},
676 {"st_dev", "device"},
677 {"st_nlink", "number of hard links"},
678 {"st_uid", "user ID of owner"},
679 {"st_gid", "group ID of owner"},
680 {"st_size", "total size, in bytes"},
681 {"st_atime", "time of last access"},
682 {"st_mtime", "time of last modification"},
683 {"st_ctime", "time of last change"},
684#ifdef HAVE_ST_BLKSIZE
685 {"st_blksize", "blocksize for filesystem I/O"},
686#endif
687#ifdef HAVE_ST_BLOCKS
688 {"st_blocks", "number of blocks allocated"},
689#endif
690#ifdef HAVE_ST_RDEV
691 {"st_rdev", "device type (if inode device)"},
692#endif
693 {0}
694};
695
696#ifdef HAVE_ST_BLKSIZE
697#define ST_BLKSIZE_IDX 10
698#else
699#define ST_BLKSIZE_IDX 9
700#endif
701
702#ifdef HAVE_ST_BLOCKS
703#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
704#else
705#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
706#endif
707
708#ifdef HAVE_ST_RDEV
709#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
710#else
711#define ST_RDEV_IDX ST_BLOCKS_IDX
712#endif
713
714static PyStructSequence_Desc stat_result_desc = {
715 "stat_result", /* name */
716 stat_result__doc__, /* doc */
717 stat_result_fields,
718 10
719};
720
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000721PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000722"statvfs_result: Result from statvfs or fstatvfs.\n\n\
723This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000724 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000725or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000726\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000727See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000728
729static PyStructSequence_Field statvfs_result_fields[] = {
730 {"f_bsize", },
731 {"f_frsize", },
732 {"f_blocks", },
733 {"f_bfree", },
734 {"f_bavail", },
735 {"f_files", },
736 {"f_ffree", },
737 {"f_favail", },
738 {"f_flag", },
739 {"f_namemax",},
740 {0}
741};
742
743static PyStructSequence_Desc statvfs_result_desc = {
744 "statvfs_result", /* name */
745 statvfs_result__doc__, /* doc */
746 statvfs_result_fields,
747 10
748};
749
750static PyTypeObject StatResultType;
751static PyTypeObject StatVFSResultType;
752
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000753static void
754fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
755{
756 PyObject *val;
Martin v. Löwisa32c9942002-09-09 16:17:47 +0000757 val = PyFloat_FromDouble(sec + 1e-9*nsec);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000758 PyStructSequence_SET_ITEM(v, index, val);
759}
760
Tim Peters5aa91602002-01-30 05:46:57 +0000761/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000762 (used by posix_stat() and posix_fstat()) */
763static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000764_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000765{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000766 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000767 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000768 if (v == NULL)
769 return NULL;
770
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000771 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000772#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000773 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000774 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000775#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000776 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000777#endif
778#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000779 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000780 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000781#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000782 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000783#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000784 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
785 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
786 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000787#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000788 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000789 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000790#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000791 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000792#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000793
794#ifdef HAVE_STAT_TV_NSEC
795 ansec = st.st_atim.tv_nsec;
796 mnsec = st.st_mtim.tv_nsec;
797 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000798#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000799 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000800#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000801 fill_time(v, 7, st.st_atime, ansec);
802 fill_time(v, 8, st.st_mtime, mnsec);
803 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000804
805#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000806 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000807 PyInt_FromLong((long)st.st_blksize));
808#endif
809#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000810 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000811 PyInt_FromLong((long)st.st_blocks));
812#endif
813#ifdef HAVE_ST_RDEV
814 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
815 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000816#endif
817
818 if (PyErr_Occurred()) {
819 Py_DECREF(v);
820 return NULL;
821 }
822
823 return v;
824}
825
Barry Warsaw53699e91996-12-10 23:23:01 +0000826static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000827posix_do_stat(PyObject *self, PyObject *args,
828 char *format,
829 int (*statfunc)(const char *, STRUCT_STAT *),
830 char *wformat,
831 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000832{
Fred Drake699f3522000-06-29 21:12:41 +0000833 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000834 char *path = NULL; /* pass this to stat; do not free() it */
835 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000836 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000837
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000838#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000839 int pathlen;
840 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000841#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000842
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000843
844#ifdef Py_WIN_WIDE_FILENAMES
845 /* If on wide-character-capable OS see if argument
846 is Unicode and if so use wide API. */
847 if (unicode_file_names()) {
848 PyUnicodeObject *po;
849 if (PyArg_ParseTuple(args, wformat, &po)) {
850 Py_UNICODE wpath[MAX_PATH+1];
851 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
852 /* the library call can blow up if the file name is too long! */
853 if (pathlen > MAX_PATH) {
854 errno = ENAMETOOLONG;
855 return posix_error();
856 }
857 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
858 /* Remove trailing slash or backslash, unless it's the current
859 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
860 */
861 if (pathlen > 0 &&
862 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
863 /* It does end with a slash -- exempt the root drive cases. */
864 /* XXX UNC root drives should also be exempted? */
865 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
866 /* leave it alone */;
867 else {
868 /* nuke the trailing backslash */
869 wpath[pathlen-1] = L'\0';
870 }
871 }
872 Py_BEGIN_ALLOW_THREADS
873 /* PyUnicode_AS_UNICODE result OK without
874 thread lock as it is a simple dereference. */
875 res = wstatfunc(wpath, &st);
876 Py_END_ALLOW_THREADS
877 if (res != 0)
878 return posix_error_with_unicode_filename(wpath);
879 return _pystat_fromstructstat(st);
880 }
881 /* Drop the argument parsing error as narrow strings
882 are also valid. */
883 PyErr_Clear();
884 }
885#endif
886
Tim Peters5aa91602002-01-30 05:46:57 +0000887 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000888 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000889 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000890 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000891
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000892#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000893 pathlen = strlen(path);
894 /* the library call can blow up if the file name is too long! */
895 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000896 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000897 errno = ENAMETOOLONG;
898 return posix_error();
899 }
900
Tim Peters500bd032001-12-19 19:05:01 +0000901 /* Remove trailing slash or backslash, unless it's the current
902 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
903 */
904 if (pathlen > 0 &&
905 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
906 /* It does end with a slash -- exempt the root drive cases. */
907 /* XXX UNC root drives should also be exempted? */
908 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
909 /* leave it alone */;
910 else {
911 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000912 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000913 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000914 path = pathcopy;
915 }
916 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000917#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000918
Barry Warsaw53699e91996-12-10 23:23:01 +0000919 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000920 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000921 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000922 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000923 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000924
Tim Peters500bd032001-12-19 19:05:01 +0000925 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000926 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000927}
928
929
930/* POSIX methods */
931
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000932PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000933"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000934Use the real uid/gid to test for access to a path. Note that most\n\
935operations will use the effective uid/gid, therefore this routine can\n\
936be used in a suid/sgid environment to test if the invoking user has the\n\
937specified access to the path. The mode argument can be F_OK to test\n\
938existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000939
940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000941posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000942{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000943 char *path;
944 int mode;
945 int res;
946
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000947 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000948 return NULL;
949 Py_BEGIN_ALLOW_THREADS
950 res = access(path, mode);
951 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +0000952 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000953}
954
Guido van Rossumd371ff11999-01-25 16:12:23 +0000955#ifndef F_OK
956#define F_OK 0
957#endif
958#ifndef R_OK
959#define R_OK 4
960#endif
961#ifndef W_OK
962#define W_OK 2
963#endif
964#ifndef X_OK
965#define X_OK 1
966#endif
967
968#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000969PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000970"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000971Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000972
973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000974posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000975{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000976 int id;
977 char *ret;
978
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000979 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000980 return NULL;
981
Guido van Rossum94f6f721999-01-06 18:42:14 +0000982 ret = ttyname(id);
983 if (ret == NULL)
984 return(posix_error());
985 return(PyString_FromString(ret));
986}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000987#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000988
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000989#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000990PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000991"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000992Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000993
994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000995posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000996{
997 char *ret;
998 char buffer[L_ctermid];
999
1000 if (!PyArg_ParseTuple(args, ":ctermid"))
1001 return NULL;
1002
Greg Wardb48bc172000-03-01 21:51:56 +00001003#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001004 ret = ctermid_r(buffer);
1005#else
1006 ret = ctermid(buffer);
1007#endif
1008 if (ret == NULL)
1009 return(posix_error());
1010 return(PyString_FromString(buffer));
1011}
1012#endif
1013
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001014PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001015"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001016Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001017
Barry Warsaw53699e91996-12-10 23:23:01 +00001018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001019posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001020{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001021#ifdef MS_WINDOWS
1022 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1023#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1024 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001025#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001026 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001027#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001028}
1029
Fred Drake4d1e64b2002-04-15 19:40:07 +00001030#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001031PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001032"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001033Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001034opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001035
1036static PyObject *
1037posix_fchdir(PyObject *self, PyObject *fdobj)
1038{
1039 return posix_fildes(fdobj, fchdir);
1040}
1041#endif /* HAVE_FCHDIR */
1042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001043
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001044PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001045"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001046Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001047
Barry Warsaw53699e91996-12-10 23:23:01 +00001048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001049posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001050{
Mark Hammondef8b6542001-05-13 08:04:26 +00001051 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001052 int i;
1053 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001054 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001055 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001056 return NULL;
1057 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001058 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001059 Py_END_ALLOW_THREADS
1060 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001061 return posix_error_with_allocated_filename(path);
1062 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001063 Py_INCREF(Py_None);
1064 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001065}
1066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001067
Martin v. Löwis244edc82001-10-04 22:44:26 +00001068#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001069PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001070"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001071Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001072
1073static PyObject *
1074posix_chroot(PyObject *self, PyObject *args)
1075{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001076 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001077}
1078#endif
1079
Guido van Rossum21142a01999-01-08 21:05:37 +00001080#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001081PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001082"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001084
1085static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001086posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001087{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001088 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001089}
1090#endif /* HAVE_FSYNC */
1091
1092#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001093
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001094#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001095extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1096#endif
1097
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001098PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001099"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001100force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001101 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001102
1103static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001104posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001105{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001106 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001107}
1108#endif /* HAVE_FDATASYNC */
1109
1110
Fredrik Lundh10723342000-07-10 16:38:09 +00001111#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001112PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001113"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001114Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001115
Barry Warsaw53699e91996-12-10 23:23:01 +00001116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001117posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001118{
Mark Hammondef8b6542001-05-13 08:04:26 +00001119 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001120 int uid, gid;
1121 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001122 if (!PyArg_ParseTuple(args, "etii:chown",
1123 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001124 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001125 return NULL;
1126 Py_BEGIN_ALLOW_THREADS
1127 res = chown(path, (uid_t) uid, (gid_t) gid);
1128 Py_END_ALLOW_THREADS
1129 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001130 return posix_error_with_allocated_filename(path);
1131 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001132 Py_INCREF(Py_None);
1133 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001134}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001135#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001136
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001137#ifdef HAVE_LCHOWN
1138PyDoc_STRVAR(posix_lchown__doc__,
1139"lchown(path, uid, gid)\n\n\
1140Change the owner and group id of path to the numeric uid and gid.\n\
1141This function will not follow symbolic links.");
1142
1143static PyObject *
1144posix_lchown(PyObject *self, PyObject *args)
1145{
1146 char *path = NULL;
1147 int uid, gid;
1148 int res;
1149 if (!PyArg_ParseTuple(args, "etii:lchown",
1150 Py_FileSystemDefaultEncoding, &path,
1151 &uid, &gid))
1152 return NULL;
1153 Py_BEGIN_ALLOW_THREADS
1154 res = lchown(path, (uid_t) uid, (gid_t) gid);
1155 Py_END_ALLOW_THREADS
1156 if (res < 0)
1157 return posix_error_with_allocated_filename(path);
1158 PyMem_Free(path);
1159 Py_INCREF(Py_None);
1160 return Py_None;
1161}
1162#endif /* HAVE_LCHOWN */
1163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001164
Guido van Rossum36bc6801995-06-14 22:54:23 +00001165#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001166PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001167"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001168Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001169
Barry Warsaw53699e91996-12-10 23:23:01 +00001170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001171posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001172{
1173 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001174 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001175 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001176 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001177 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001178#if defined(PYOS_OS2) && defined(PYCC_GCC)
1179 res = _getcwd2(buf, sizeof buf);
1180#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001181 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001182#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001183 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001184 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001186 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001187}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001188
1189PyDoc_STRVAR(posix_getcwdu__doc__,
1190"getcwdu() -> path\n\n\
1191Return a unicode string representing the current working directory.");
1192
1193static PyObject *
1194posix_getcwdu(PyObject *self, PyObject *args)
1195{
1196 char buf[1026];
1197 char *res;
1198 if (!PyArg_ParseTuple(args, ":getcwd"))
1199 return NULL;
1200
1201#ifdef Py_WIN_WIDE_FILENAMES
1202 if (unicode_file_names()) {
1203 wchar_t *wres;
1204 wchar_t wbuf[1026];
1205 Py_BEGIN_ALLOW_THREADS
1206 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1207 Py_END_ALLOW_THREADS
1208 if (wres == NULL)
1209 return posix_error();
1210 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1211 }
1212#endif
1213
1214 Py_BEGIN_ALLOW_THREADS
1215#if defined(PYOS_OS2) && defined(PYCC_GCC)
1216 res = _getcwd2(buf, sizeof buf);
1217#else
1218 res = getcwd(buf, sizeof buf);
1219#endif
1220 Py_END_ALLOW_THREADS
1221 if (res == NULL)
1222 return posix_error();
1223 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1224}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001225#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001227
Guido van Rossumb6775db1994-08-01 11:34:53 +00001228#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001229PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001230"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001231Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001232
Barry Warsaw53699e91996-12-10 23:23:01 +00001233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001234posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001235{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001236 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001237}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001238#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001239
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001240
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001241PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001242"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001243Return a list containing the names of the entries in the directory.\n\
1244\n\
1245 path: path of directory to list\n\
1246\n\
1247The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001248entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001249
Barry Warsaw53699e91996-12-10 23:23:01 +00001250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001251posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001252{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001253 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001254 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001255#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001256
Barry Warsaw53699e91996-12-10 23:23:01 +00001257 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001258 HANDLE hFindFile;
1259 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001260 /* MAX_PATH characters could mean a bigger encoded string */
1261 char namebuf[MAX_PATH*2+5];
1262 char *bufptr = namebuf;
1263 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001264
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001265#ifdef Py_WIN_WIDE_FILENAMES
1266 /* If on wide-character-capable OS see if argument
1267 is Unicode and if so use wide API. */
1268 if (unicode_file_names()) {
1269 PyUnicodeObject *po;
1270 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1271 WIN32_FIND_DATAW wFileData;
1272 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1273 Py_UNICODE wch;
1274 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1275 wnamebuf[MAX_PATH] = L'\0';
1276 len = wcslen(wnamebuf);
1277 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1278 if (wch != L'/' && wch != L'\\' && wch != L':')
1279 wnamebuf[len++] = L'/';
1280 wcscpy(wnamebuf + len, L"*.*");
1281 if ((d = PyList_New(0)) == NULL)
1282 return NULL;
1283 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1284 if (hFindFile == INVALID_HANDLE_VALUE) {
1285 errno = GetLastError();
1286 if (errno == ERROR_FILE_NOT_FOUND) {
1287 return d;
1288 }
1289 Py_DECREF(d);
1290 return win32_error_unicode("FindFirstFileW", wnamebuf);
1291 }
1292 do {
1293 if (wFileData.cFileName[0] == L'.' &&
1294 (wFileData.cFileName[1] == L'\0' ||
1295 wFileData.cFileName[1] == L'.' &&
1296 wFileData.cFileName[2] == L'\0'))
1297 continue;
1298 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1299 if (v == NULL) {
1300 Py_DECREF(d);
1301 d = NULL;
1302 break;
1303 }
1304 if (PyList_Append(d, v) != 0) {
1305 Py_DECREF(v);
1306 Py_DECREF(d);
1307 d = NULL;
1308 break;
1309 }
1310 Py_DECREF(v);
1311 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1312
1313 if (FindClose(hFindFile) == FALSE) {
1314 Py_DECREF(d);
1315 return win32_error_unicode("FindClose", wnamebuf);
1316 }
1317 return d;
1318 }
1319 /* Drop the argument parsing error as narrow strings
1320 are also valid. */
1321 PyErr_Clear();
1322 }
1323#endif
1324
Tim Peters5aa91602002-01-30 05:46:57 +00001325 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001326 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001327 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001328 if (len > 0) {
1329 char ch = namebuf[len-1];
1330 if (ch != SEP && ch != ALTSEP && ch != ':')
1331 namebuf[len++] = '/';
1332 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001333 strcpy(namebuf + len, "*.*");
1334
Barry Warsaw53699e91996-12-10 23:23:01 +00001335 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001336 return NULL;
1337
1338 hFindFile = FindFirstFile(namebuf, &FileData);
1339 if (hFindFile == INVALID_HANDLE_VALUE) {
1340 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001341 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001342 return d;
1343 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001344 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001345 }
1346 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001347 if (FileData.cFileName[0] == '.' &&
1348 (FileData.cFileName[1] == '\0' ||
1349 FileData.cFileName[1] == '.' &&
1350 FileData.cFileName[2] == '\0'))
1351 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001352 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001353 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001354 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001355 d = NULL;
1356 break;
1357 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001358 if (PyList_Append(d, v) != 0) {
1359 Py_DECREF(v);
1360 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001361 d = NULL;
1362 break;
1363 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001364 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001365 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1366
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001367 if (FindClose(hFindFile) == FALSE) {
1368 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001369 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001370 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001371
1372 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001373
Tim Peters0bb44a42000-09-15 07:44:49 +00001374#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001375
1376#ifndef MAX_PATH
1377#define MAX_PATH CCHMAXPATH
1378#endif
1379 char *name, *pt;
1380 int len;
1381 PyObject *d, *v;
1382 char namebuf[MAX_PATH+5];
1383 HDIR hdir = 1;
1384 ULONG srchcnt = 1;
1385 FILEFINDBUF3 ep;
1386 APIRET rc;
1387
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001388 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001389 return NULL;
1390 if (len >= MAX_PATH) {
1391 PyErr_SetString(PyExc_ValueError, "path too long");
1392 return NULL;
1393 }
1394 strcpy(namebuf, name);
1395 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001396 if (*pt == ALTSEP)
1397 *pt = SEP;
1398 if (namebuf[len-1] != SEP)
1399 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001400 strcpy(namebuf + len, "*.*");
1401
1402 if ((d = PyList_New(0)) == NULL)
1403 return NULL;
1404
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001405 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1406 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001407 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001408 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1409 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1410 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001411
1412 if (rc != NO_ERROR) {
1413 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001414 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001415 }
1416
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001417 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001418 do {
1419 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001420 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001421 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001422
1423 strcpy(namebuf, ep.achName);
1424
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001425 /* Leave Case of Name Alone -- In Native Form */
1426 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001427
1428 v = PyString_FromString(namebuf);
1429 if (v == NULL) {
1430 Py_DECREF(d);
1431 d = NULL;
1432 break;
1433 }
1434 if (PyList_Append(d, v) != 0) {
1435 Py_DECREF(v);
1436 Py_DECREF(d);
1437 d = NULL;
1438 break;
1439 }
1440 Py_DECREF(v);
1441 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1442 }
1443
1444 return d;
1445#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001446
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001447 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001448 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001449 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001450 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001451 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001452 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001453 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001454 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001455 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001456 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001457 closedir(dirp);
1458 return NULL;
1459 }
1460 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001461 if (ep->d_name[0] == '.' &&
1462 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001463 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001464 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001465 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001466 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001467 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001468 d = NULL;
1469 break;
1470 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001471 if (PyList_Append(d, v) != 0) {
1472 Py_DECREF(v);
1473 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001474 d = NULL;
1475 break;
1476 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001477 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001478 }
1479 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001480
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001481 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001482
Tim Peters0bb44a42000-09-15 07:44:49 +00001483#endif /* which OS */
1484} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001485
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001486#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001487/* A helper function for abspath on win32 */
1488static PyObject *
1489posix__getfullpathname(PyObject *self, PyObject *args)
1490{
1491 /* assume encoded strings wont more than double no of chars */
1492 char inbuf[MAX_PATH*2];
1493 char *inbufp = inbuf;
1494 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1495 char outbuf[MAX_PATH*2];
1496 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001497#ifdef Py_WIN_WIDE_FILENAMES
1498 if (unicode_file_names()) {
1499 PyUnicodeObject *po;
1500 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1501 Py_UNICODE woutbuf[MAX_PATH*2];
1502 Py_UNICODE *wtemp;
1503 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1504 sizeof(woutbuf)/sizeof(woutbuf[0]),
1505 woutbuf, &wtemp))
1506 return win32_error("GetFullPathName", "");
1507 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1508 }
1509 /* Drop the argument parsing error as narrow strings
1510 are also valid. */
1511 PyErr_Clear();
1512 }
1513#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001514 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1515 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001516 &insize))
1517 return NULL;
1518 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1519 outbuf, &temp))
1520 return win32_error("GetFullPathName", inbuf);
1521 return PyString_FromString(outbuf);
1522} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001523#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001525PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001526"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001527Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001528
Barry Warsaw53699e91996-12-10 23:23:01 +00001529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001530posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001531{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001532 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001533 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001534 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001535
1536#ifdef Py_WIN_WIDE_FILENAMES
1537 if (unicode_file_names()) {
1538 PyUnicodeObject *po;
1539 if (PyArg_ParseTuple(args, "U|i:mkdir", &po)) {
1540 Py_BEGIN_ALLOW_THREADS
1541 /* PyUnicode_AS_UNICODE OK without thread lock as
1542 it is a simple dereference. */
1543 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1544 Py_END_ALLOW_THREADS
1545 if (res < 0)
1546 return posix_error();
1547 Py_INCREF(Py_None);
1548 return Py_None;
1549 }
1550 /* Drop the argument parsing error as narrow strings
1551 are also valid. */
1552 PyErr_Clear();
1553 }
1554#endif
1555
Tim Peters5aa91602002-01-30 05:46:57 +00001556 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001557 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001558 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001559 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001560#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001561 res = mkdir(path);
1562#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001563 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001564#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001565 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001566 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001567 return posix_error_with_allocated_filename(path);
1568 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001569 Py_INCREF(Py_None);
1570 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001571}
1572
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001573
Guido van Rossumb6775db1994-08-01 11:34:53 +00001574#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001575#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1576#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1577#include <sys/resource.h>
1578#endif
1579#endif
1580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001581PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001582"nice(inc) -> new_priority\n\n\
1583Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001584
Barry Warsaw53699e91996-12-10 23:23:01 +00001585static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001586posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001587{
1588 int increment, value;
1589
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001590 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001591 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001592
1593 /* There are two flavours of 'nice': one that returns the new
1594 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001595 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1596 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001597
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001598 If we are of the nice family that returns the new priority, we
1599 need to clear errno before the call, and check if errno is filled
1600 before calling posix_error() on a returnvalue of -1, because the
1601 -1 may be the actual new priority! */
1602
1603 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001604 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001605#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001606 if (value == 0)
1607 value = getpriority(PRIO_PROCESS, 0);
1608#endif
1609 if (value == -1 && errno != 0)
1610 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001611 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001612 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001613}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001614#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001615
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001616
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001617PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001618"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001619Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001620
Barry Warsaw53699e91996-12-10 23:23:01 +00001621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001622posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001623{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001624#ifdef MS_WINDOWS
1625 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1626#else
1627 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1628#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001629}
1630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001632PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001633"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001634Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001635
Barry Warsaw53699e91996-12-10 23:23:01 +00001636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001637posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001638{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001639#ifdef MS_WINDOWS
1640 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1641#else
1642 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1643#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001644}
1645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001646
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001647PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001648"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001649Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001650
Barry Warsaw53699e91996-12-10 23:23:01 +00001651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001652posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001653{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001654#ifdef MS_WINDOWS
1655 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1656#else
1657 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1658#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001659}
1660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001661
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001662#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001663PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001664"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001665Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001666
Barry Warsaw53699e91996-12-10 23:23:01 +00001667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001668posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001670 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001671 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001672 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001673 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001674 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001675 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001676 Py_END_ALLOW_THREADS
1677 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001678}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001679#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001680
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001681
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001682PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001683"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001684Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001685
Barry Warsaw53699e91996-12-10 23:23:01 +00001686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001687posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001688{
1689 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001690 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001691 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001692 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001693 if (i < 0)
1694 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001695 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001696}
1697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001698
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001699PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001700"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001701Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001702
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001703PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001704"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001705Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001706
Barry Warsaw53699e91996-12-10 23:23:01 +00001707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001708posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001709{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001710#ifdef MS_WINDOWS
1711 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1712#else
1713 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1714#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001715}
1716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001717
Guido van Rossumb6775db1994-08-01 11:34:53 +00001718#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001719PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001720"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001721Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001722
Barry Warsaw53699e91996-12-10 23:23:01 +00001723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001724posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001725{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001726 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001727 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001728 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001729 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001730 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001731 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001732 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001733 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001734 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001735 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001736 u.sysname,
1737 u.nodename,
1738 u.release,
1739 u.version,
1740 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001741}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001742#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001743
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001744static int
1745extract_time(PyObject *t, long* sec, long* usec)
1746{
1747 long intval;
1748 if (PyFloat_Check(t)) {
1749 double tval = PyFloat_AsDouble(t);
1750 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1751 if (!intobj)
1752 return -1;
1753 intval = PyInt_AsLong(intobj);
1754 Py_DECREF(intobj);
1755 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001756 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001757 if (*usec < 0)
1758 /* If rounding gave us a negative number,
1759 truncate. */
1760 *usec = 0;
1761 return 0;
1762 }
1763 intval = PyInt_AsLong(t);
1764 if (intval == -1 && PyErr_Occurred())
1765 return -1;
1766 *sec = intval;
1767 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001768 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001769}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001770
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001771PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001772"utime(path, (atime, utime))\n\
1773utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001774Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001775second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001776
Barry Warsaw53699e91996-12-10 23:23:01 +00001777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001778posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001779{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001780 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001781 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001782 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001783 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001784
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001785#if defined(HAVE_UTIMES)
1786 struct timeval buf[2];
1787#define ATIME buf[0].tv_sec
1788#define MTIME buf[1].tv_sec
1789#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001790/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001791 struct utimbuf buf;
1792#define ATIME buf.actime
1793#define MTIME buf.modtime
1794#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001795#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001796 time_t buf[2];
1797#define ATIME buf[0]
1798#define MTIME buf[1]
1799#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001800#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001801
Barry Warsaw3cef8562000-05-01 16:17:24 +00001802 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001803 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001804 if (arg == Py_None) {
1805 /* optional time values not given */
1806 Py_BEGIN_ALLOW_THREADS
1807 res = utime(path, NULL);
1808 Py_END_ALLOW_THREADS
1809 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001810 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001811 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001812 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001813 return NULL;
1814 }
1815 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001816 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1817 &atime, &ausec) == -1)
1818 return NULL;
1819 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1820 &mtime, &musec) == -1)
1821 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001822 ATIME = atime;
1823 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001824#ifdef HAVE_UTIMES
1825 buf[0].tv_usec = ausec;
1826 buf[1].tv_usec = musec;
1827 Py_BEGIN_ALLOW_THREADS
1828 res = utimes(path, buf);
1829 Py_END_ALLOW_THREADS
1830#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001831 Py_BEGIN_ALLOW_THREADS
1832 res = utime(path, UTIME_ARG);
1833 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001834#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00001835 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001836 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001837 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001838 Py_INCREF(Py_None);
1839 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001840#undef UTIME_ARG
1841#undef ATIME
1842#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001843}
1844
Guido van Rossum85e3b011991-06-03 12:42:10 +00001845
Guido van Rossum3b066191991-06-04 19:40:25 +00001846/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001849"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001850Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001851
Barry Warsaw53699e91996-12-10 23:23:01 +00001852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001853posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001854{
1855 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001856 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001857 return NULL;
1858 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001859 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001860}
1861
Martin v. Löwis114619e2002-10-07 06:44:21 +00001862#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
1863static void
1864free_string_array(char **array, int count)
1865{
1866 int i;
1867 for (i = 0; i < count; i++)
1868 PyMem_Free(array[i]);
1869 PyMem_DEL(array);
1870}
1871#endif
1872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001873
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001874#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001875PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001876"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001877Execute an executable path with arguments, replacing current process.\n\
1878\n\
1879 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001880 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001881
Barry Warsaw53699e91996-12-10 23:23:01 +00001882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001883posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001884{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001885 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001886 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001887 char **argvlist;
1888 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001889 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001890
Guido van Rossum89b33251993-10-22 14:26:06 +00001891 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001892 argv is a list or tuple of strings. */
1893
Martin v. Löwis114619e2002-10-07 06:44:21 +00001894 if (!PyArg_ParseTuple(args, "etO:execv",
1895 Py_FileSystemDefaultEncoding,
1896 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001897 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001898 if (PyList_Check(argv)) {
1899 argc = PyList_Size(argv);
1900 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001901 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001902 else if (PyTuple_Check(argv)) {
1903 argc = PyTuple_Size(argv);
1904 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001905 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001906 else {
Fred Drake661ea262000-10-24 19:57:45 +00001907 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001908 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00001909 return NULL;
1910 }
1911
1912 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001913 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001914 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001915 return NULL;
1916 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001917
Barry Warsaw53699e91996-12-10 23:23:01 +00001918 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00001919 if (argvlist == NULL) {
1920 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001921 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00001922 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001923 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00001924 if (!PyArg_Parse((*getitem)(argv, i), "et",
1925 Py_FileSystemDefaultEncoding,
1926 &argvlist[i])) {
1927 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00001928 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001929 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001930 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00001931 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001932
Guido van Rossum85e3b011991-06-03 12:42:10 +00001933 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001934 }
1935 argvlist[argc] = NULL;
1936
Guido van Rossumb6775db1994-08-01 11:34:53 +00001937#ifdef BAD_EXEC_PROTOTYPES
1938 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001939#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001940 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001941#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001942
Guido van Rossum85e3b011991-06-03 12:42:10 +00001943 /* If we get here it's definitely an error */
1944
Martin v. Löwis114619e2002-10-07 06:44:21 +00001945 free_string_array(argvlist, argc);
1946 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001947 return posix_error();
1948}
1949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001950
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001952"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001953Execute a path with arguments and environment, replacing current process.\n\
1954\n\
1955 path: path of executable file\n\
1956 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001957 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001958
Barry Warsaw53699e91996-12-10 23:23:01 +00001959static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001960posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001961{
1962 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001963 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001964 char **argvlist;
1965 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001966 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001967 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001968 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00001969 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001970
1971 /* execve has three arguments: (path, argv, env), where
1972 argv is a list or tuple of strings and env is a dictionary
1973 like posix.environ. */
1974
Martin v. Löwis114619e2002-10-07 06:44:21 +00001975 if (!PyArg_ParseTuple(args, "etOO:execve",
1976 Py_FileSystemDefaultEncoding,
1977 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001978 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001979 if (PyList_Check(argv)) {
1980 argc = PyList_Size(argv);
1981 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001982 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001983 else if (PyTuple_Check(argv)) {
1984 argc = PyTuple_Size(argv);
1985 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001986 }
1987 else {
Fred Drake661ea262000-10-24 19:57:45 +00001988 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001989 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001990 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001991 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001992 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001993 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001994 }
1995
Guido van Rossum50422b42000-04-26 20:34:28 +00001996 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001997 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001998 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001999 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002000 }
2001
Barry Warsaw53699e91996-12-10 23:23:01 +00002002 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002003 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002004 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002005 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002006 }
2007 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002008 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002009 "et;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002010 &argvlist[i]))
2011 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002012 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002013 goto fail_1;
2014 }
2015 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002016 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002017 argvlist[argc] = NULL;
2018
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002019 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00002020 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002021 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002022 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002023 goto fail_1;
2024 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002025 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002026 keys = PyMapping_Keys(env);
2027 vals = PyMapping_Values(env);
2028 if (!keys || !vals)
2029 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002030
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002031 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002032 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002033 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002034
2035 key = PyList_GetItem(keys, pos);
2036 val = PyList_GetItem(vals, pos);
2037 if (!key || !val)
2038 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002039
Fred Drake661ea262000-10-24 19:57:45 +00002040 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
2041 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002042 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002043 goto fail_2;
2044 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002045
2046#if defined(PYOS_OS2)
2047 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2048 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2049#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002050 len = PyString_Size(key) + PyString_Size(val) + 2;
2051 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002052 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002053 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002054 goto fail_2;
2055 }
Tim Petersc8996f52001-12-03 20:41:00 +00002056 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002057 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002058#if defined(PYOS_OS2)
2059 }
2060#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002061 }
2062 envlist[envc] = 0;
2063
Guido van Rossumb6775db1994-08-01 11:34:53 +00002064
2065#ifdef BAD_EXEC_PROTOTYPES
2066 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002067#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002068 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002069#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002070
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002071 /* If we get here it's definitely an error */
2072
2073 (void) posix_error();
2074
2075 fail_2:
2076 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002077 PyMem_DEL(envlist[envc]);
2078 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002079 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002080 free_string_array(argvlist,lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002081 Py_XDECREF(vals);
2082 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002083 fail_0:
2084 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002085 return NULL;
2086}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002087#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002089
Guido van Rossuma1065681999-01-25 23:20:23 +00002090#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002091PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002092"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002093Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002094\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002095 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002096 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002097 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002098
2099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002100posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002101{
2102 char *path;
2103 PyObject *argv;
2104 char **argvlist;
2105 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002106 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002107 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002108
2109 /* spawnv has three arguments: (mode, path, argv), where
2110 argv is a list or tuple of strings. */
2111
Martin v. Löwis114619e2002-10-07 06:44:21 +00002112 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2113 Py_FileSystemDefaultEncoding,
2114 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002115 return NULL;
2116 if (PyList_Check(argv)) {
2117 argc = PyList_Size(argv);
2118 getitem = PyList_GetItem;
2119 }
2120 else if (PyTuple_Check(argv)) {
2121 argc = PyTuple_Size(argv);
2122 getitem = PyTuple_GetItem;
2123 }
2124 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00002125 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002126 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002127 return NULL;
2128 }
2129
2130 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002131 if (argvlist == NULL) {
2132 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002133 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002134 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002135 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002136 if (!PyArg_Parse((*getitem)(argv, i), "et",
2137 Py_FileSystemDefaultEncoding,
2138 &argvlist[i])) {
2139 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002140 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002141 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002142 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002143 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002144 }
2145 }
2146 argvlist[argc] = NULL;
2147
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002148#if defined(PYOS_OS2) && defined(PYCC_GCC)
2149 Py_BEGIN_ALLOW_THREADS
2150 spawnval = spawnv(mode, path, argvlist);
2151 Py_END_ALLOW_THREADS
2152#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002153 if (mode == _OLD_P_OVERLAY)
2154 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002155
Tim Peters25059d32001-12-07 20:35:43 +00002156 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002157 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002158 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002159#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002160
Martin v. Löwis114619e2002-10-07 06:44:21 +00002161 free_string_array(argvlist, argc);
2162 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002163
Fred Drake699f3522000-06-29 21:12:41 +00002164 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002165 return posix_error();
2166 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002167#if SIZEOF_LONG == SIZEOF_VOID_P
2168 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002169#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002170 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002171#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002172}
2173
2174
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002175PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002176"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002177Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002178\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002179 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002180 path: path of executable file\n\
2181 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002182 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002183
2184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002185posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002186{
2187 char *path;
2188 PyObject *argv, *env;
2189 char **argvlist;
2190 char **envlist;
2191 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2192 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002193 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002194 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002195 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002196
2197 /* spawnve has four arguments: (mode, path, argv, env), where
2198 argv is a list or tuple of strings and env is a dictionary
2199 like posix.environ. */
2200
Martin v. Löwis114619e2002-10-07 06:44:21 +00002201 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2202 Py_FileSystemDefaultEncoding,
2203 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002204 return NULL;
2205 if (PyList_Check(argv)) {
2206 argc = PyList_Size(argv);
2207 getitem = PyList_GetItem;
2208 }
2209 else if (PyTuple_Check(argv)) {
2210 argc = PyTuple_Size(argv);
2211 getitem = PyTuple_GetItem;
2212 }
2213 else {
Fred Drake661ea262000-10-24 19:57:45 +00002214 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002215 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002216 }
2217 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00002218 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002219 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002220 }
2221
2222 argvlist = PyMem_NEW(char *, argc+1);
2223 if (argvlist == NULL) {
2224 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002225 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002226 }
2227 for (i = 0; i < argc; i++) {
2228 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002229 "et;spawnve() arg 2 must contain only strings",
2230 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002231 &argvlist[i]))
2232 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002233 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002234 goto fail_1;
2235 }
2236 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002237 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002238 argvlist[argc] = NULL;
2239
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002240 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00002241 envlist = PyMem_NEW(char *, i + 1);
2242 if (envlist == NULL) {
2243 PyErr_NoMemory();
2244 goto fail_1;
2245 }
2246 envc = 0;
2247 keys = PyMapping_Keys(env);
2248 vals = PyMapping_Values(env);
2249 if (!keys || !vals)
2250 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002251
Guido van Rossuma1065681999-01-25 23:20:23 +00002252 for (pos = 0; pos < i; pos++) {
2253 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002254 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002255
2256 key = PyList_GetItem(keys, pos);
2257 val = PyList_GetItem(vals, pos);
2258 if (!key || !val)
2259 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002260
Fred Drake661ea262000-10-24 19:57:45 +00002261 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
2262 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002263 {
2264 goto fail_2;
2265 }
Tim Petersc8996f52001-12-03 20:41:00 +00002266 len = PyString_Size(key) + PyString_Size(val) + 2;
2267 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002268 if (p == NULL) {
2269 PyErr_NoMemory();
2270 goto fail_2;
2271 }
Tim Petersc8996f52001-12-03 20:41:00 +00002272 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002273 envlist[envc++] = p;
2274 }
2275 envlist[envc] = 0;
2276
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002277#if defined(PYOS_OS2) && defined(PYCC_GCC)
2278 Py_BEGIN_ALLOW_THREADS
2279 spawnval = spawnve(mode, path, argvlist, envlist);
2280 Py_END_ALLOW_THREADS
2281#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002282 if (mode == _OLD_P_OVERLAY)
2283 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002284
2285 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002286 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002287 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002288#endif
Tim Peters25059d32001-12-07 20:35:43 +00002289
Fred Drake699f3522000-06-29 21:12:41 +00002290 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002291 (void) posix_error();
2292 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002293#if SIZEOF_LONG == SIZEOF_VOID_P
2294 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002295#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002296 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002297#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002298
2299 fail_2:
2300 while (--envc >= 0)
2301 PyMem_DEL(envlist[envc]);
2302 PyMem_DEL(envlist);
2303 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002304 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002305 Py_XDECREF(vals);
2306 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002307 fail_0:
2308 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002309 return res;
2310}
2311#endif /* HAVE_SPAWNV */
2312
2313
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002314#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002315PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002316"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002317Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2318\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002319Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002320
2321static PyObject *
2322posix_fork1(self, args)
2323 PyObject *self;
2324 PyObject *args;
2325{
2326 int pid;
2327 if (!PyArg_ParseTuple(args, ":fork1"))
2328 return NULL;
2329 pid = fork1();
2330 if (pid == -1)
2331 return posix_error();
2332 PyOS_AfterFork();
2333 return PyInt_FromLong((long)pid);
2334}
2335#endif
2336
2337
Guido van Rossumad0ee831995-03-01 10:34:45 +00002338#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002339PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002340"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002341Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002342Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002343
Barry Warsaw53699e91996-12-10 23:23:01 +00002344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002345posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002346{
2347 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002348 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002349 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002350 pid = fork();
2351 if (pid == -1)
2352 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002353 if (pid == 0)
2354 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002355 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002356}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002357#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002358
Fred Drake8cef4cf2000-06-28 16:40:38 +00002359#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
2360#ifdef HAVE_PTY_H
2361#include <pty.h>
2362#else
2363#ifdef HAVE_LIBUTIL_H
2364#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002365#endif /* HAVE_LIBUTIL_H */
2366#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002367#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002368
Thomas Wouters70c21a12000-07-14 14:28:33 +00002369#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002370PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002371"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002372Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002373
2374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002375posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002376{
2377 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002378#ifndef HAVE_OPENPTY
2379 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002380#endif
2381
Fred Drake8cef4cf2000-06-28 16:40:38 +00002382 if (!PyArg_ParseTuple(args, ":openpty"))
2383 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002384
2385#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002386 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2387 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00002388#else
2389 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2390 if (slave_name == NULL)
2391 return posix_error();
2392
2393 slave_fd = open(slave_name, O_RDWR);
2394 if (slave_fd < 0)
2395 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002396#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002397
Fred Drake8cef4cf2000-06-28 16:40:38 +00002398 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002399
Fred Drake8cef4cf2000-06-28 16:40:38 +00002400}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002401#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002402
2403#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002404PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002405"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002406Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2407Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002408To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002409
2410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002411posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002412{
2413 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002414
Fred Drake8cef4cf2000-06-28 16:40:38 +00002415 if (!PyArg_ParseTuple(args, ":forkpty"))
2416 return NULL;
2417 pid = forkpty(&master_fd, NULL, NULL, NULL);
2418 if (pid == -1)
2419 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002420 if (pid == 0)
2421 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002422 return Py_BuildValue("(ii)", pid, master_fd);
2423}
2424#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002425
Guido van Rossumad0ee831995-03-01 10:34:45 +00002426#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002427PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002428"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002429Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002430
Barry Warsaw53699e91996-12-10 23:23:01 +00002431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002432posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002433{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002434 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002435 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002436 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002437}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002438#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002440
Guido van Rossumad0ee831995-03-01 10:34:45 +00002441#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002442PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002443"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002444Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002445
Barry Warsaw53699e91996-12-10 23:23:01 +00002446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002447posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002448{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002449 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002450 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002451 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002452}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002453#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002454
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002455
Guido van Rossumad0ee831995-03-01 10:34:45 +00002456#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002457PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002458"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002459Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002460
Barry Warsaw53699e91996-12-10 23:23:01 +00002461static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002462posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002463{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002464 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002465 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002466 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002467}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002468#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002469
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002470
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002471PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002472"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002473Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002474
Barry Warsaw53699e91996-12-10 23:23:01 +00002475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002476posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002477{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002478 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002479 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002480 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002481}
2482
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002483
Fred Drakec9680921999-12-13 16:37:25 +00002484#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002485PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002486"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002487Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002488
2489static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002490posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002491{
2492 PyObject *result = NULL;
2493
2494 if (PyArg_ParseTuple(args, ":getgroups")) {
2495#ifdef NGROUPS_MAX
2496#define MAX_GROUPS NGROUPS_MAX
2497#else
2498 /* defined to be 16 on Solaris7, so this should be a small number */
2499#define MAX_GROUPS 64
2500#endif
2501 gid_t grouplist[MAX_GROUPS];
2502 int n;
2503
2504 n = getgroups(MAX_GROUPS, grouplist);
2505 if (n < 0)
2506 posix_error();
2507 else {
2508 result = PyList_New(n);
2509 if (result != NULL) {
2510 PyObject *o;
2511 int i;
2512 for (i = 0; i < n; ++i) {
2513 o = PyInt_FromLong((long)grouplist[i]);
2514 if (o == NULL) {
2515 Py_DECREF(result);
2516 result = NULL;
2517 break;
2518 }
2519 PyList_SET_ITEM(result, i, o);
2520 }
2521 }
2522 }
2523 }
2524 return result;
2525}
2526#endif
2527
Martin v. Löwis606edc12002-06-13 21:09:11 +00002528#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002529PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002530"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002531Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002532
2533static PyObject *
2534posix_getpgid(PyObject *self, PyObject *args)
2535{
2536 int pid, pgid;
2537 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2538 return NULL;
2539 pgid = getpgid(pid);
2540 if (pgid < 0)
2541 return posix_error();
2542 return PyInt_FromLong((long)pgid);
2543}
2544#endif /* HAVE_GETPGID */
2545
2546
Guido van Rossumb6775db1994-08-01 11:34:53 +00002547#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002548PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002549"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002550Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002551
Barry Warsaw53699e91996-12-10 23:23:01 +00002552static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002553posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002554{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002555 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002556 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002557#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002558 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002559#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002560 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002561#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002562}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002563#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002565
Guido van Rossumb6775db1994-08-01 11:34:53 +00002566#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002567PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002568"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002569Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002570
Barry Warsaw53699e91996-12-10 23:23:01 +00002571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002572posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002573{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002574 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002575 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002576#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002577 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002578#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002579 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002580#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002581 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002582 Py_INCREF(Py_None);
2583 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002584}
2585
Guido van Rossumb6775db1994-08-01 11:34:53 +00002586#endif /* HAVE_SETPGRP */
2587
Guido van Rossumad0ee831995-03-01 10:34:45 +00002588#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002589PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002590"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002591Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002592
Barry Warsaw53699e91996-12-10 23:23:01 +00002593static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002594posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002595{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002596 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002597 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002598 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002599}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002600#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002602
Fred Drake12c6e2d1999-12-14 21:25:03 +00002603#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002604PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002605"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002606Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002607
2608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002609posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002610{
2611 PyObject *result = NULL;
2612
2613 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002614 char *name;
2615 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002616
Fred Drakea30680b2000-12-06 21:24:28 +00002617 errno = 0;
2618 name = getlogin();
2619 if (name == NULL) {
2620 if (errno)
2621 posix_error();
2622 else
2623 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002624 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002625 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002626 else
2627 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002628 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002629 }
2630 return result;
2631}
2632#endif
2633
Guido van Rossumad0ee831995-03-01 10:34:45 +00002634#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002635PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002636"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002637Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002638
Barry Warsaw53699e91996-12-10 23:23:01 +00002639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002640posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002641{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002642 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002643 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002644 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002645}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002646#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002647
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002648
Guido van Rossumad0ee831995-03-01 10:34:45 +00002649#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002650PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002651"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002652Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002653
Barry Warsaw53699e91996-12-10 23:23:01 +00002654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002655posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002656{
2657 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002658 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002659 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002660#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002661 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2662 APIRET rc;
2663 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002664 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002665
2666 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2667 APIRET rc;
2668 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002669 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002670
2671 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002672 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002673#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002674 if (kill(pid, sig) == -1)
2675 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002676#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002677 Py_INCREF(Py_None);
2678 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002679}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002680#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002681
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002682#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002683PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002684"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002685Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002686
2687static PyObject *
2688posix_killpg(PyObject *self, PyObject *args)
2689{
2690 int pgid, sig;
2691 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2692 return NULL;
2693 if (killpg(pgid, sig) == -1)
2694 return posix_error();
2695 Py_INCREF(Py_None);
2696 return Py_None;
2697}
2698#endif
2699
Guido van Rossumc0125471996-06-28 18:55:32 +00002700#ifdef HAVE_PLOCK
2701
2702#ifdef HAVE_SYS_LOCK_H
2703#include <sys/lock.h>
2704#endif
2705
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002706PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002707"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002708Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002709
Barry Warsaw53699e91996-12-10 23:23:01 +00002710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002711posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002712{
2713 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002714 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002715 return NULL;
2716 if (plock(op) == -1)
2717 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002718 Py_INCREF(Py_None);
2719 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002720}
2721#endif
2722
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002723
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002724#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002725PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002726"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002727Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002728
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002729#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002730#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002731static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002732async_system(const char *command)
2733{
2734 char *p, errormsg[256], args[1024];
2735 RESULTCODES rcodes;
2736 APIRET rc;
2737 char *shell = getenv("COMSPEC");
2738 if (!shell)
2739 shell = "cmd";
2740
2741 strcpy(args, shell);
2742 p = &args[ strlen(args)+1 ];
2743 strcpy(p, "/c ");
2744 strcat(p, command);
2745 p += strlen(p) + 1;
2746 *p = '\0';
2747
2748 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002749 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002750 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002751 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002752 &rcodes, shell);
2753 return rc;
2754}
2755
Guido van Rossumd48f2521997-12-05 22:19:34 +00002756static FILE *
2757popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002758{
2759 HFILE rhan, whan;
2760 FILE *retfd = NULL;
2761 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2762
Guido van Rossumd48f2521997-12-05 22:19:34 +00002763 if (rc != NO_ERROR) {
2764 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002765 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002766 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002767
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002768 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2769 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002770
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002771 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2772 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002773
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002774 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2775 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002776
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002777 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002778 }
2779
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002780 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2781 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002782
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002783 if (rc == NO_ERROR)
2784 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2785
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002786 close(oldfd); /* And Close Saved STDOUT Handle */
2787 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002788
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002789 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2790 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002791
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002792 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2793 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002794
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002795 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2796 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002797
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002798 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002799 }
2800
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002801 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2802 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002803
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002804 if (rc == NO_ERROR)
2805 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2806
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002807 close(oldfd); /* And Close Saved STDIN Handle */
2808 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002809
Guido van Rossumd48f2521997-12-05 22:19:34 +00002810 } else {
2811 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002812 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002813 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002814}
2815
2816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002817posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002818{
2819 char *name;
2820 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002821 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002822 FILE *fp;
2823 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002824 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002825 return NULL;
2826 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002827 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002828 Py_END_ALLOW_THREADS
2829 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002830 return os2_error(err);
2831
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002832 f = PyFile_FromFile(fp, name, mode, fclose);
2833 if (f != NULL)
2834 PyFile_SetBufSize(f, bufsize);
2835 return f;
2836}
2837
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002838#elif defined(PYCC_GCC)
2839
2840/* standard posix version of popen() support */
2841static PyObject *
2842posix_popen(PyObject *self, PyObject *args)
2843{
2844 char *name;
2845 char *mode = "r";
2846 int bufsize = -1;
2847 FILE *fp;
2848 PyObject *f;
2849 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2850 return NULL;
2851 Py_BEGIN_ALLOW_THREADS
2852 fp = popen(name, mode);
2853 Py_END_ALLOW_THREADS
2854 if (fp == NULL)
2855 return posix_error();
2856 f = PyFile_FromFile(fp, name, mode, pclose);
2857 if (f != NULL)
2858 PyFile_SetBufSize(f, bufsize);
2859 return f;
2860}
2861
2862/* fork() under OS/2 has lots'o'warts
2863 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2864 * most of this code is a ripoff of the win32 code, but using the
2865 * capabilities of EMX's C library routines
2866 */
2867
2868/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2869#define POPEN_1 1
2870#define POPEN_2 2
2871#define POPEN_3 3
2872#define POPEN_4 4
2873
2874static PyObject *_PyPopen(char *, int, int, int);
2875static int _PyPclose(FILE *file);
2876
2877/*
2878 * Internal dictionary mapping popen* file pointers to process handles,
2879 * for use when retrieving the process exit code. See _PyPclose() below
2880 * for more information on this dictionary's use.
2881 */
2882static PyObject *_PyPopenProcs = NULL;
2883
2884/* os2emx version of popen2()
2885 *
2886 * The result of this function is a pipe (file) connected to the
2887 * process's stdin, and a pipe connected to the process's stdout.
2888 */
2889
2890static PyObject *
2891os2emx_popen2(PyObject *self, PyObject *args)
2892{
2893 PyObject *f;
2894 int tm=0;
2895
2896 char *cmdstring;
2897 char *mode = "t";
2898 int bufsize = -1;
2899 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2900 return NULL;
2901
2902 if (*mode == 't')
2903 tm = O_TEXT;
2904 else if (*mode != 'b') {
2905 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2906 return NULL;
2907 } else
2908 tm = O_BINARY;
2909
2910 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2911
2912 return f;
2913}
2914
2915/*
2916 * Variation on os2emx.popen2
2917 *
2918 * The result of this function is 3 pipes - the process's stdin,
2919 * stdout and stderr
2920 */
2921
2922static PyObject *
2923os2emx_popen3(PyObject *self, PyObject *args)
2924{
2925 PyObject *f;
2926 int tm = 0;
2927
2928 char *cmdstring;
2929 char *mode = "t";
2930 int bufsize = -1;
2931 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2932 return NULL;
2933
2934 if (*mode == 't')
2935 tm = O_TEXT;
2936 else if (*mode != 'b') {
2937 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2938 return NULL;
2939 } else
2940 tm = O_BINARY;
2941
2942 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2943
2944 return f;
2945}
2946
2947/*
2948 * Variation on os2emx.popen2
2949 *
2950 * The result of this function is 2 pipes - the processes stdin,
2951 * and stdout+stderr combined as a single pipe.
2952 */
2953
2954static PyObject *
2955os2emx_popen4(PyObject *self, PyObject *args)
2956{
2957 PyObject *f;
2958 int tm = 0;
2959
2960 char *cmdstring;
2961 char *mode = "t";
2962 int bufsize = -1;
2963 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2964 return NULL;
2965
2966 if (*mode == 't')
2967 tm = O_TEXT;
2968 else if (*mode != 'b') {
2969 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2970 return NULL;
2971 } else
2972 tm = O_BINARY;
2973
2974 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2975
2976 return f;
2977}
2978
2979/* a couple of structures for convenient handling of multiple
2980 * file handles and pipes
2981 */
2982struct file_ref
2983{
2984 int handle;
2985 int flags;
2986};
2987
2988struct pipe_ref
2989{
2990 int rd;
2991 int wr;
2992};
2993
2994/* The following code is derived from the win32 code */
2995
2996static PyObject *
2997_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2998{
2999 struct file_ref stdio[3];
3000 struct pipe_ref p_fd[3];
3001 FILE *p_s[3];
3002 int file_count, i, pipe_err, pipe_pid;
3003 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3004 PyObject *f, *p_f[3];
3005
3006 /* file modes for subsequent fdopen's on pipe handles */
3007 if (mode == O_TEXT)
3008 {
3009 rd_mode = "rt";
3010 wr_mode = "wt";
3011 }
3012 else
3013 {
3014 rd_mode = "rb";
3015 wr_mode = "wb";
3016 }
3017
3018 /* prepare shell references */
3019 if ((shell = getenv("EMXSHELL")) == NULL)
3020 if ((shell = getenv("COMSPEC")) == NULL)
3021 {
3022 errno = ENOENT;
3023 return posix_error();
3024 }
3025
3026 sh_name = _getname(shell);
3027 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3028 opt = "/c";
3029 else
3030 opt = "-c";
3031
3032 /* save current stdio fds + their flags, and set not inheritable */
3033 i = pipe_err = 0;
3034 while (pipe_err >= 0 && i < 3)
3035 {
3036 pipe_err = stdio[i].handle = dup(i);
3037 stdio[i].flags = fcntl(i, F_GETFD, 0);
3038 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3039 i++;
3040 }
3041 if (pipe_err < 0)
3042 {
3043 /* didn't get them all saved - clean up and bail out */
3044 int saved_err = errno;
3045 while (i-- > 0)
3046 {
3047 close(stdio[i].handle);
3048 }
3049 errno = saved_err;
3050 return posix_error();
3051 }
3052
3053 /* create pipe ends */
3054 file_count = 2;
3055 if (n == POPEN_3)
3056 file_count = 3;
3057 i = pipe_err = 0;
3058 while ((pipe_err == 0) && (i < file_count))
3059 pipe_err = pipe((int *)&p_fd[i++]);
3060 if (pipe_err < 0)
3061 {
3062 /* didn't get them all made - clean up and bail out */
3063 while (i-- > 0)
3064 {
3065 close(p_fd[i].wr);
3066 close(p_fd[i].rd);
3067 }
3068 errno = EPIPE;
3069 return posix_error();
3070 }
3071
3072 /* change the actual standard IO streams over temporarily,
3073 * making the retained pipe ends non-inheritable
3074 */
3075 pipe_err = 0;
3076
3077 /* - stdin */
3078 if (dup2(p_fd[0].rd, 0) == 0)
3079 {
3080 close(p_fd[0].rd);
3081 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3082 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3083 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3084 {
3085 close(p_fd[0].wr);
3086 pipe_err = -1;
3087 }
3088 }
3089 else
3090 {
3091 pipe_err = -1;
3092 }
3093
3094 /* - stdout */
3095 if (pipe_err == 0)
3096 {
3097 if (dup2(p_fd[1].wr, 1) == 1)
3098 {
3099 close(p_fd[1].wr);
3100 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3101 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3102 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3103 {
3104 close(p_fd[1].rd);
3105 pipe_err = -1;
3106 }
3107 }
3108 else
3109 {
3110 pipe_err = -1;
3111 }
3112 }
3113
3114 /* - stderr, as required */
3115 if (pipe_err == 0)
3116 switch (n)
3117 {
3118 case POPEN_3:
3119 {
3120 if (dup2(p_fd[2].wr, 2) == 2)
3121 {
3122 close(p_fd[2].wr);
3123 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3124 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3125 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3126 {
3127 close(p_fd[2].rd);
3128 pipe_err = -1;
3129 }
3130 }
3131 else
3132 {
3133 pipe_err = -1;
3134 }
3135 break;
3136 }
3137
3138 case POPEN_4:
3139 {
3140 if (dup2(1, 2) != 2)
3141 {
3142 pipe_err = -1;
3143 }
3144 break;
3145 }
3146 }
3147
3148 /* spawn the child process */
3149 if (pipe_err == 0)
3150 {
3151 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3152 if (pipe_pid == -1)
3153 {
3154 pipe_err = -1;
3155 }
3156 else
3157 {
3158 /* save the PID into the FILE structure
3159 * NOTE: this implementation doesn't actually
3160 * take advantage of this, but do it for
3161 * completeness - AIM Apr01
3162 */
3163 for (i = 0; i < file_count; i++)
3164 p_s[i]->_pid = pipe_pid;
3165 }
3166 }
3167
3168 /* reset standard IO to normal */
3169 for (i = 0; i < 3; i++)
3170 {
3171 dup2(stdio[i].handle, i);
3172 fcntl(i, F_SETFD, stdio[i].flags);
3173 close(stdio[i].handle);
3174 }
3175
3176 /* if any remnant problems, clean up and bail out */
3177 if (pipe_err < 0)
3178 {
3179 for (i = 0; i < 3; i++)
3180 {
3181 close(p_fd[i].rd);
3182 close(p_fd[i].wr);
3183 }
3184 errno = EPIPE;
3185 return posix_error_with_filename(cmdstring);
3186 }
3187
3188 /* build tuple of file objects to return */
3189 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3190 PyFile_SetBufSize(p_f[0], bufsize);
3191 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3192 PyFile_SetBufSize(p_f[1], bufsize);
3193 if (n == POPEN_3)
3194 {
3195 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3196 PyFile_SetBufSize(p_f[0], bufsize);
3197 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3198 }
3199 else
3200 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3201
3202 /*
3203 * Insert the files we've created into the process dictionary
3204 * all referencing the list with the process handle and the
3205 * initial number of files (see description below in _PyPclose).
3206 * Since if _PyPclose later tried to wait on a process when all
3207 * handles weren't closed, it could create a deadlock with the
3208 * child, we spend some energy here to try to ensure that we
3209 * either insert all file handles into the dictionary or none
3210 * at all. It's a little clumsy with the various popen modes
3211 * and variable number of files involved.
3212 */
3213 if (!_PyPopenProcs)
3214 {
3215 _PyPopenProcs = PyDict_New();
3216 }
3217
3218 if (_PyPopenProcs)
3219 {
3220 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3221 int ins_rc[3];
3222
3223 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3224 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3225
3226 procObj = PyList_New(2);
3227 pidObj = PyInt_FromLong((long) pipe_pid);
3228 intObj = PyInt_FromLong((long) file_count);
3229
3230 if (procObj && pidObj && intObj)
3231 {
3232 PyList_SetItem(procObj, 0, pidObj);
3233 PyList_SetItem(procObj, 1, intObj);
3234
3235 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3236 if (fileObj[0])
3237 {
3238 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3239 fileObj[0],
3240 procObj);
3241 }
3242 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3243 if (fileObj[1])
3244 {
3245 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3246 fileObj[1],
3247 procObj);
3248 }
3249 if (file_count >= 3)
3250 {
3251 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3252 if (fileObj[2])
3253 {
3254 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3255 fileObj[2],
3256 procObj);
3257 }
3258 }
3259
3260 if (ins_rc[0] < 0 || !fileObj[0] ||
3261 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3262 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3263 {
3264 /* Something failed - remove any dictionary
3265 * entries that did make it.
3266 */
3267 if (!ins_rc[0] && fileObj[0])
3268 {
3269 PyDict_DelItem(_PyPopenProcs,
3270 fileObj[0]);
3271 }
3272 if (!ins_rc[1] && fileObj[1])
3273 {
3274 PyDict_DelItem(_PyPopenProcs,
3275 fileObj[1]);
3276 }
3277 if (!ins_rc[2] && fileObj[2])
3278 {
3279 PyDict_DelItem(_PyPopenProcs,
3280 fileObj[2]);
3281 }
3282 }
3283 }
3284
3285 /*
3286 * Clean up our localized references for the dictionary keys
3287 * and value since PyDict_SetItem will Py_INCREF any copies
3288 * that got placed in the dictionary.
3289 */
3290 Py_XDECREF(procObj);
3291 Py_XDECREF(fileObj[0]);
3292 Py_XDECREF(fileObj[1]);
3293 Py_XDECREF(fileObj[2]);
3294 }
3295
3296 /* Child is launched. */
3297 return f;
3298}
3299
3300/*
3301 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3302 * exit code for the child process and return as a result of the close.
3303 *
3304 * This function uses the _PyPopenProcs dictionary in order to map the
3305 * input file pointer to information about the process that was
3306 * originally created by the popen* call that created the file pointer.
3307 * The dictionary uses the file pointer as a key (with one entry
3308 * inserted for each file returned by the original popen* call) and a
3309 * single list object as the value for all files from a single call.
3310 * The list object contains the Win32 process handle at [0], and a file
3311 * count at [1], which is initialized to the total number of file
3312 * handles using that list.
3313 *
3314 * This function closes whichever handle it is passed, and decrements
3315 * the file count in the dictionary for the process handle pointed to
3316 * by this file. On the last close (when the file count reaches zero),
3317 * this function will wait for the child process and then return its
3318 * exit code as the result of the close() operation. This permits the
3319 * files to be closed in any order - it is always the close() of the
3320 * final handle that will return the exit code.
3321 */
3322
3323 /* RED_FLAG 31-Aug-2000 Tim
3324 * This is always called (today!) between a pair of
3325 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3326 * macros. So the thread running this has no valid thread state, as
3327 * far as Python is concerned. However, this calls some Python API
3328 * functions that cannot be called safely without a valid thread
3329 * state, in particular PyDict_GetItem.
3330 * As a temporary hack (although it may last for years ...), we
3331 * *rely* on not having a valid thread state in this function, in
3332 * order to create our own "from scratch".
3333 * This will deadlock if _PyPclose is ever called by a thread
3334 * holding the global lock.
3335 * (The OS/2 EMX thread support appears to cover the case where the
3336 * lock is already held - AIM Apr01)
3337 */
3338
3339static int _PyPclose(FILE *file)
3340{
3341 int result;
3342 int exit_code;
3343 int pipe_pid;
3344 PyObject *procObj, *pidObj, *intObj, *fileObj;
3345 int file_count;
3346#ifdef WITH_THREAD
3347 PyInterpreterState* pInterpreterState;
3348 PyThreadState* pThreadState;
3349#endif
3350
3351 /* Close the file handle first, to ensure it can't block the
3352 * child from exiting if it's the last handle.
3353 */
3354 result = fclose(file);
3355
3356#ifdef WITH_THREAD
3357 /* Bootstrap a valid thread state into existence. */
3358 pInterpreterState = PyInterpreterState_New();
3359 if (!pInterpreterState) {
3360 /* Well, we're hosed now! We don't have a thread
3361 * state, so can't call a nice error routine, or raise
3362 * an exception. Just die.
3363 */
3364 Py_FatalError("unable to allocate interpreter state "
3365 "when closing popen object.");
3366 return -1; /* unreachable */
3367 }
3368 pThreadState = PyThreadState_New(pInterpreterState);
3369 if (!pThreadState) {
3370 Py_FatalError("unable to allocate thread state "
3371 "when closing popen object.");
3372 return -1; /* unreachable */
3373 }
3374 /* Grab the global lock. Note that this will deadlock if the
3375 * current thread already has the lock! (see RED_FLAG comments
3376 * before this function)
3377 */
3378 PyEval_RestoreThread(pThreadState);
3379#endif
3380
3381 if (_PyPopenProcs)
3382 {
3383 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3384 (procObj = PyDict_GetItem(_PyPopenProcs,
3385 fileObj)) != NULL &&
3386 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3387 (intObj = PyList_GetItem(procObj,1)) != NULL)
3388 {
3389 pipe_pid = (int) PyInt_AsLong(pidObj);
3390 file_count = (int) PyInt_AsLong(intObj);
3391
3392 if (file_count > 1)
3393 {
3394 /* Still other files referencing process */
3395 file_count--;
3396 PyList_SetItem(procObj,1,
3397 PyInt_FromLong((long) file_count));
3398 }
3399 else
3400 {
3401 /* Last file for this process */
3402 if (result != EOF &&
3403 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3404 {
3405 /* extract exit status */
3406 if (WIFEXITED(exit_code))
3407 {
3408 result = WEXITSTATUS(exit_code);
3409 }
3410 else
3411 {
3412 errno = EPIPE;
3413 result = -1;
3414 }
3415 }
3416 else
3417 {
3418 /* Indicate failure - this will cause the file object
3419 * to raise an I/O error and translate the last
3420 * error code from errno. We do have a problem with
3421 * last errors that overlap the normal errno table,
3422 * but that's a consistent problem with the file object.
3423 */
3424 result = -1;
3425 }
3426 }
3427
3428 /* Remove this file pointer from dictionary */
3429 PyDict_DelItem(_PyPopenProcs, fileObj);
3430
3431 if (PyDict_Size(_PyPopenProcs) == 0)
3432 {
3433 Py_DECREF(_PyPopenProcs);
3434 _PyPopenProcs = NULL;
3435 }
3436
3437 } /* if object retrieval ok */
3438
3439 Py_XDECREF(fileObj);
3440 } /* if _PyPopenProcs */
3441
3442#ifdef WITH_THREAD
3443 /* Tear down the thread & interpreter states.
3444 * Note that interpreter state clear & delete functions automatically
3445 * call the thread clear & delete functions, and indeed insist on
3446 * doing that themselves. The lock must be held during the clear, but
3447 * need not be held during the delete.
3448 */
3449 PyInterpreterState_Clear(pInterpreterState);
3450 PyEval_ReleaseThread(pThreadState);
3451 PyInterpreterState_Delete(pInterpreterState);
3452#endif
3453
3454 return result;
3455}
3456
3457#endif /* PYCC_??? */
3458
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003459#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003460
3461/*
3462 * Portable 'popen' replacement for Win32.
3463 *
3464 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3465 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003466 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003467 */
3468
3469#include <malloc.h>
3470#include <io.h>
3471#include <fcntl.h>
3472
3473/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3474#define POPEN_1 1
3475#define POPEN_2 2
3476#define POPEN_3 3
3477#define POPEN_4 4
3478
3479static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003480static int _PyPclose(FILE *file);
3481
3482/*
3483 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003484 * for use when retrieving the process exit code. See _PyPclose() below
3485 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003486 */
3487static PyObject *_PyPopenProcs = NULL;
3488
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003489
3490/* popen that works from a GUI.
3491 *
3492 * The result of this function is a pipe (file) connected to the
3493 * processes stdin or stdout, depending on the requested mode.
3494 */
3495
3496static PyObject *
3497posix_popen(PyObject *self, PyObject *args)
3498{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003499 PyObject *f, *s;
3500 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003501
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003502 char *cmdstring;
3503 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003504 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003505 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003506 return NULL;
3507
3508 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003509
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003510 if (*mode == 'r')
3511 tm = _O_RDONLY;
3512 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003513 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003514 return NULL;
3515 } else
3516 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003517
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003518 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003519 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003520 return NULL;
3521 }
3522
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003523 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003524 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003525 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003526 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003527 else
3528 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3529
3530 return f;
3531}
3532
3533/* Variation on win32pipe.popen
3534 *
3535 * The result of this function is a pipe (file) connected to the
3536 * process's stdin, and a pipe connected to the process's stdout.
3537 */
3538
3539static PyObject *
3540win32_popen2(PyObject *self, PyObject *args)
3541{
3542 PyObject *f;
3543 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003544
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003545 char *cmdstring;
3546 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003547 int bufsize = -1;
3548 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003549 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003550
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003551 if (*mode == 't')
3552 tm = _O_TEXT;
3553 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003554 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003555 return NULL;
3556 } else
3557 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003558
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003559 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003560 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003561 return NULL;
3562 }
3563
3564 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003565
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003566 return f;
3567}
3568
3569/*
3570 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003571 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003572 * The result of this function is 3 pipes - the process's stdin,
3573 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003574 */
3575
3576static PyObject *
3577win32_popen3(PyObject *self, PyObject *args)
3578{
3579 PyObject *f;
3580 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003581
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003582 char *cmdstring;
3583 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003584 int bufsize = -1;
3585 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003586 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003587
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003588 if (*mode == 't')
3589 tm = _O_TEXT;
3590 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003591 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003592 return NULL;
3593 } else
3594 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003595
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003596 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003597 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003598 return NULL;
3599 }
3600
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003601 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003602
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003603 return f;
3604}
3605
3606/*
3607 * Variation on win32pipe.popen
3608 *
Tim Peters5aa91602002-01-30 05:46:57 +00003609 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003610 * and stdout+stderr combined as a single pipe.
3611 */
3612
3613static PyObject *
3614win32_popen4(PyObject *self, PyObject *args)
3615{
3616 PyObject *f;
3617 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003618
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003619 char *cmdstring;
3620 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003621 int bufsize = -1;
3622 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003623 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003624
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003625 if (*mode == 't')
3626 tm = _O_TEXT;
3627 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003628 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003629 return NULL;
3630 } else
3631 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003632
3633 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003634 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003635 return NULL;
3636 }
3637
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003638 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003639
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003640 return f;
3641}
3642
Mark Hammond08501372001-01-31 07:30:29 +00003643static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003644_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003645 HANDLE hStdin,
3646 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003647 HANDLE hStderr,
3648 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003649{
3650 PROCESS_INFORMATION piProcInfo;
3651 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003652 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003653 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003654 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003655 int i;
3656 int x;
3657
3658 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003659 char *comshell;
3660
Tim Peters92e4dd82002-10-05 01:47:34 +00003661 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003662 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3663 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003664
3665 /* Explicitly check if we are using COMMAND.COM. If we are
3666 * then use the w9xpopen hack.
3667 */
3668 comshell = s1 + x;
3669 while (comshell >= s1 && *comshell != '\\')
3670 --comshell;
3671 ++comshell;
3672
3673 if (GetVersion() < 0x80000000 &&
3674 _stricmp(comshell, "command.com") != 0) {
3675 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003676 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003677 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003678 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003679 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003680 }
3681 else {
3682 /*
Tim Peters402d5982001-08-27 06:37:48 +00003683 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3684 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003685 */
Mark Hammond08501372001-01-31 07:30:29 +00003686 char modulepath[_MAX_PATH];
3687 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003688 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3689 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003690 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003691 x = i+1;
3692 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003693 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003694 strncat(modulepath,
3695 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003696 (sizeof(modulepath)/sizeof(modulepath[0]))
3697 -strlen(modulepath));
3698 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003699 /* Eeek - file-not-found - possibly an embedding
3700 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003701 */
Tim Peters5aa91602002-01-30 05:46:57 +00003702 strncpy(modulepath,
3703 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003704 sizeof(modulepath)/sizeof(modulepath[0]));
3705 if (modulepath[strlen(modulepath)-1] != '\\')
3706 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003707 strncat(modulepath,
3708 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003709 (sizeof(modulepath)/sizeof(modulepath[0]))
3710 -strlen(modulepath));
3711 /* No where else to look - raise an easily identifiable
3712 error, rather than leaving Windows to report
3713 "file not found" - as the user is probably blissfully
3714 unaware this shim EXE is used, and it will confuse them.
3715 (well, it confused me for a while ;-)
3716 */
3717 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003718 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003719 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003720 "for popen to work with your shell "
3721 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003722 szConsoleSpawn);
3723 return FALSE;
3724 }
3725 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003726 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003727 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003728 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003729
Tim Peters92e4dd82002-10-05 01:47:34 +00003730 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003731 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003732 /* To maintain correct argument passing semantics,
3733 we pass the command-line as it stands, and allow
3734 quoting to be applied. w9xpopen.exe will then
3735 use its argv vector, and re-quote the necessary
3736 args for the ultimate child process.
3737 */
Tim Peters75cdad52001-11-28 22:07:30 +00003738 PyOS_snprintf(
3739 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003740 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003741 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003742 s1,
3743 s3,
3744 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003745 /* Not passing CREATE_NEW_CONSOLE has been known to
3746 cause random failures on win9x. Specifically a
3747 dialog:
3748 "Your program accessed mem currently in use at xxx"
3749 and a hopeful warning about the stability of your
3750 system.
3751 Cost is Ctrl+C wont kill children, but anyone
3752 who cares can have a go!
3753 */
3754 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003755 }
3756 }
3757
3758 /* Could be an else here to try cmd.exe / command.com in the path
3759 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003760 else {
Tim Peters402d5982001-08-27 06:37:48 +00003761 PyErr_SetString(PyExc_RuntimeError,
3762 "Cannot locate a COMSPEC environment variable to "
3763 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003764 return FALSE;
3765 }
Tim Peters5aa91602002-01-30 05:46:57 +00003766
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003767 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3768 siStartInfo.cb = sizeof(STARTUPINFO);
3769 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3770 siStartInfo.hStdInput = hStdin;
3771 siStartInfo.hStdOutput = hStdout;
3772 siStartInfo.hStdError = hStderr;
3773 siStartInfo.wShowWindow = SW_HIDE;
3774
3775 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003776 s2,
3777 NULL,
3778 NULL,
3779 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003780 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003781 NULL,
3782 NULL,
3783 &siStartInfo,
3784 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003785 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003786 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003787
Mark Hammondb37a3732000-08-14 04:47:33 +00003788 /* Return process handle */
3789 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003790 return TRUE;
3791 }
Tim Peters402d5982001-08-27 06:37:48 +00003792 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003793 return FALSE;
3794}
3795
3796/* The following code is based off of KB: Q190351 */
3797
3798static PyObject *
3799_PyPopen(char *cmdstring, int mode, int n)
3800{
3801 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3802 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003803 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003804
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003805 SECURITY_ATTRIBUTES saAttr;
3806 BOOL fSuccess;
3807 int fd1, fd2, fd3;
3808 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003809 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003810 PyObject *f;
3811
3812 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3813 saAttr.bInheritHandle = TRUE;
3814 saAttr.lpSecurityDescriptor = NULL;
3815
3816 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3817 return win32_error("CreatePipe", NULL);
3818
3819 /* Create new output read handle and the input write handle. Set
3820 * the inheritance properties to FALSE. Otherwise, the child inherits
3821 * the these handles; resulting in non-closeable handles to the pipes
3822 * being created. */
3823 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003824 GetCurrentProcess(), &hChildStdinWrDup, 0,
3825 FALSE,
3826 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003827 if (!fSuccess)
3828 return win32_error("DuplicateHandle", NULL);
3829
3830 /* Close the inheritable version of ChildStdin
3831 that we're using. */
3832 CloseHandle(hChildStdinWr);
3833
3834 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3835 return win32_error("CreatePipe", NULL);
3836
3837 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003838 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3839 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003840 if (!fSuccess)
3841 return win32_error("DuplicateHandle", NULL);
3842
3843 /* Close the inheritable version of ChildStdout
3844 that we're using. */
3845 CloseHandle(hChildStdoutRd);
3846
3847 if (n != POPEN_4) {
3848 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3849 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003850 fSuccess = DuplicateHandle(GetCurrentProcess(),
3851 hChildStderrRd,
3852 GetCurrentProcess(),
3853 &hChildStderrRdDup, 0,
3854 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003855 if (!fSuccess)
3856 return win32_error("DuplicateHandle", NULL);
3857 /* Close the inheritable version of ChildStdErr that we're using. */
3858 CloseHandle(hChildStderrRd);
3859 }
Tim Peters5aa91602002-01-30 05:46:57 +00003860
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003861 switch (n) {
3862 case POPEN_1:
3863 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3864 case _O_WRONLY | _O_TEXT:
3865 /* Case for writing to child Stdin in text mode. */
3866 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3867 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003868 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003869 PyFile_SetBufSize(f, 0);
3870 /* We don't care about these pipes anymore, so close them. */
3871 CloseHandle(hChildStdoutRdDup);
3872 CloseHandle(hChildStderrRdDup);
3873 break;
3874
3875 case _O_RDONLY | _O_TEXT:
3876 /* Case for reading from child Stdout in text mode. */
3877 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3878 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003879 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003880 PyFile_SetBufSize(f, 0);
3881 /* We don't care about these pipes anymore, so close them. */
3882 CloseHandle(hChildStdinWrDup);
3883 CloseHandle(hChildStderrRdDup);
3884 break;
3885
3886 case _O_RDONLY | _O_BINARY:
3887 /* Case for readinig from child Stdout in binary mode. */
3888 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3889 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003890 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003891 PyFile_SetBufSize(f, 0);
3892 /* We don't care about these pipes anymore, so close them. */
3893 CloseHandle(hChildStdinWrDup);
3894 CloseHandle(hChildStderrRdDup);
3895 break;
3896
3897 case _O_WRONLY | _O_BINARY:
3898 /* Case for writing to child Stdin in binary mode. */
3899 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3900 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003901 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003902 PyFile_SetBufSize(f, 0);
3903 /* We don't care about these pipes anymore, so close them. */
3904 CloseHandle(hChildStdoutRdDup);
3905 CloseHandle(hChildStderrRdDup);
3906 break;
3907 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003908 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003909 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003910
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003911 case POPEN_2:
3912 case POPEN_4:
3913 {
3914 char *m1, *m2;
3915 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003916
Tim Peters7dca21e2002-08-19 00:42:29 +00003917 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003918 m1 = "r";
3919 m2 = "w";
3920 } else {
3921 m1 = "rb";
3922 m2 = "wb";
3923 }
3924
3925 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3926 f1 = _fdopen(fd1, m2);
3927 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3928 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003929 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003930 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003931 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003932 PyFile_SetBufSize(p2, 0);
3933
3934 if (n != 4)
3935 CloseHandle(hChildStderrRdDup);
3936
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003937 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003938 Py_XDECREF(p1);
3939 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003940 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003941 break;
3942 }
Tim Peters5aa91602002-01-30 05:46:57 +00003943
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003944 case POPEN_3:
3945 {
3946 char *m1, *m2;
3947 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003948
Tim Peters7dca21e2002-08-19 00:42:29 +00003949 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003950 m1 = "r";
3951 m2 = "w";
3952 } else {
3953 m1 = "rb";
3954 m2 = "wb";
3955 }
3956
3957 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3958 f1 = _fdopen(fd1, m2);
3959 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3960 f2 = _fdopen(fd2, m1);
3961 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3962 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003963 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003964 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3965 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003966 PyFile_SetBufSize(p1, 0);
3967 PyFile_SetBufSize(p2, 0);
3968 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003969 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003970 Py_XDECREF(p1);
3971 Py_XDECREF(p2);
3972 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003973 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003974 break;
3975 }
3976 }
3977
3978 if (n == POPEN_4) {
3979 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003980 hChildStdinRd,
3981 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003982 hChildStdoutWr,
3983 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003984 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003985 }
3986 else {
3987 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003988 hChildStdinRd,
3989 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003990 hChildStderrWr,
3991 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003992 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003993 }
3994
Mark Hammondb37a3732000-08-14 04:47:33 +00003995 /*
3996 * Insert the files we've created into the process dictionary
3997 * all referencing the list with the process handle and the
3998 * initial number of files (see description below in _PyPclose).
3999 * Since if _PyPclose later tried to wait on a process when all
4000 * handles weren't closed, it could create a deadlock with the
4001 * child, we spend some energy here to try to ensure that we
4002 * either insert all file handles into the dictionary or none
4003 * at all. It's a little clumsy with the various popen modes
4004 * and variable number of files involved.
4005 */
4006 if (!_PyPopenProcs) {
4007 _PyPopenProcs = PyDict_New();
4008 }
4009
4010 if (_PyPopenProcs) {
4011 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4012 int ins_rc[3];
4013
4014 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4015 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4016
4017 procObj = PyList_New(2);
4018 hProcessObj = PyLong_FromVoidPtr(hProcess);
4019 intObj = PyInt_FromLong(file_count);
4020
4021 if (procObj && hProcessObj && intObj) {
4022 PyList_SetItem(procObj,0,hProcessObj);
4023 PyList_SetItem(procObj,1,intObj);
4024
4025 fileObj[0] = PyLong_FromVoidPtr(f1);
4026 if (fileObj[0]) {
4027 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4028 fileObj[0],
4029 procObj);
4030 }
4031 if (file_count >= 2) {
4032 fileObj[1] = PyLong_FromVoidPtr(f2);
4033 if (fileObj[1]) {
4034 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4035 fileObj[1],
4036 procObj);
4037 }
4038 }
4039 if (file_count >= 3) {
4040 fileObj[2] = PyLong_FromVoidPtr(f3);
4041 if (fileObj[2]) {
4042 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4043 fileObj[2],
4044 procObj);
4045 }
4046 }
4047
4048 if (ins_rc[0] < 0 || !fileObj[0] ||
4049 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4050 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4051 /* Something failed - remove any dictionary
4052 * entries that did make it.
4053 */
4054 if (!ins_rc[0] && fileObj[0]) {
4055 PyDict_DelItem(_PyPopenProcs,
4056 fileObj[0]);
4057 }
4058 if (!ins_rc[1] && fileObj[1]) {
4059 PyDict_DelItem(_PyPopenProcs,
4060 fileObj[1]);
4061 }
4062 if (!ins_rc[2] && fileObj[2]) {
4063 PyDict_DelItem(_PyPopenProcs,
4064 fileObj[2]);
4065 }
4066 }
4067 }
Tim Peters5aa91602002-01-30 05:46:57 +00004068
Mark Hammondb37a3732000-08-14 04:47:33 +00004069 /*
4070 * Clean up our localized references for the dictionary keys
4071 * and value since PyDict_SetItem will Py_INCREF any copies
4072 * that got placed in the dictionary.
4073 */
4074 Py_XDECREF(procObj);
4075 Py_XDECREF(fileObj[0]);
4076 Py_XDECREF(fileObj[1]);
4077 Py_XDECREF(fileObj[2]);
4078 }
4079
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004080 /* Child is launched. Close the parents copy of those pipe
4081 * handles that only the child should have open. You need to
4082 * make sure that no handles to the write end of the output pipe
4083 * are maintained in this process or else the pipe will not close
4084 * when the child process exits and the ReadFile will hang. */
4085
4086 if (!CloseHandle(hChildStdinRd))
4087 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004088
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004089 if (!CloseHandle(hChildStdoutWr))
4090 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004091
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004092 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4093 return win32_error("CloseHandle", NULL);
4094
4095 return f;
4096}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004097
4098/*
4099 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4100 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004101 *
4102 * This function uses the _PyPopenProcs dictionary in order to map the
4103 * input file pointer to information about the process that was
4104 * originally created by the popen* call that created the file pointer.
4105 * The dictionary uses the file pointer as a key (with one entry
4106 * inserted for each file returned by the original popen* call) and a
4107 * single list object as the value for all files from a single call.
4108 * The list object contains the Win32 process handle at [0], and a file
4109 * count at [1], which is initialized to the total number of file
4110 * handles using that list.
4111 *
4112 * This function closes whichever handle it is passed, and decrements
4113 * the file count in the dictionary for the process handle pointed to
4114 * by this file. On the last close (when the file count reaches zero),
4115 * this function will wait for the child process and then return its
4116 * exit code as the result of the close() operation. This permits the
4117 * files to be closed in any order - it is always the close() of the
4118 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004119 */
Tim Peters736aa322000-09-01 06:51:24 +00004120
4121 /* RED_FLAG 31-Aug-2000 Tim
4122 * This is always called (today!) between a pair of
4123 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4124 * macros. So the thread running this has no valid thread state, as
4125 * far as Python is concerned. However, this calls some Python API
4126 * functions that cannot be called safely without a valid thread
4127 * state, in particular PyDict_GetItem.
4128 * As a temporary hack (although it may last for years ...), we
4129 * *rely* on not having a valid thread state in this function, in
4130 * order to create our own "from scratch".
4131 * This will deadlock if _PyPclose is ever called by a thread
4132 * holding the global lock.
4133 */
4134
Fredrik Lundh56055a42000-07-23 19:47:12 +00004135static int _PyPclose(FILE *file)
4136{
Fredrik Lundh20318932000-07-26 17:29:12 +00004137 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004138 DWORD exit_code;
4139 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004140 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4141 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004142#ifdef WITH_THREAD
4143 PyInterpreterState* pInterpreterState;
4144 PyThreadState* pThreadState;
4145#endif
4146
Fredrik Lundh20318932000-07-26 17:29:12 +00004147 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004148 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004149 */
4150 result = fclose(file);
4151
Tim Peters736aa322000-09-01 06:51:24 +00004152#ifdef WITH_THREAD
4153 /* Bootstrap a valid thread state into existence. */
4154 pInterpreterState = PyInterpreterState_New();
4155 if (!pInterpreterState) {
4156 /* Well, we're hosed now! We don't have a thread
4157 * state, so can't call a nice error routine, or raise
4158 * an exception. Just die.
4159 */
4160 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004161 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004162 return -1; /* unreachable */
4163 }
4164 pThreadState = PyThreadState_New(pInterpreterState);
4165 if (!pThreadState) {
4166 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004167 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004168 return -1; /* unreachable */
4169 }
4170 /* Grab the global lock. Note that this will deadlock if the
4171 * current thread already has the lock! (see RED_FLAG comments
4172 * before this function)
4173 */
4174 PyEval_RestoreThread(pThreadState);
4175#endif
4176
Fredrik Lundh56055a42000-07-23 19:47:12 +00004177 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004178 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4179 (procObj = PyDict_GetItem(_PyPopenProcs,
4180 fileObj)) != NULL &&
4181 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4182 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4183
4184 hProcess = PyLong_AsVoidPtr(hProcessObj);
4185 file_count = PyInt_AsLong(intObj);
4186
4187 if (file_count > 1) {
4188 /* Still other files referencing process */
4189 file_count--;
4190 PyList_SetItem(procObj,1,
4191 PyInt_FromLong(file_count));
4192 } else {
4193 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004194 if (result != EOF &&
4195 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4196 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004197 /* Possible truncation here in 16-bit environments, but
4198 * real exit codes are just the lower byte in any event.
4199 */
4200 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004201 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004202 /* Indicate failure - this will cause the file object
4203 * to raise an I/O error and translate the last Win32
4204 * error code from errno. We do have a problem with
4205 * last errors that overlap the normal errno table,
4206 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004207 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004208 if (result != EOF) {
4209 /* If the error wasn't from the fclose(), then
4210 * set errno for the file object error handling.
4211 */
4212 errno = GetLastError();
4213 }
4214 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004215 }
4216
4217 /* Free up the native handle at this point */
4218 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004219 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004220
Mark Hammondb37a3732000-08-14 04:47:33 +00004221 /* Remove this file pointer from dictionary */
4222 PyDict_DelItem(_PyPopenProcs, fileObj);
4223
4224 if (PyDict_Size(_PyPopenProcs) == 0) {
4225 Py_DECREF(_PyPopenProcs);
4226 _PyPopenProcs = NULL;
4227 }
4228
4229 } /* if object retrieval ok */
4230
4231 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004232 } /* if _PyPopenProcs */
4233
Tim Peters736aa322000-09-01 06:51:24 +00004234#ifdef WITH_THREAD
4235 /* Tear down the thread & interpreter states.
4236 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004237 * call the thread clear & delete functions, and indeed insist on
4238 * doing that themselves. The lock must be held during the clear, but
4239 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004240 */
4241 PyInterpreterState_Clear(pInterpreterState);
4242 PyEval_ReleaseThread(pThreadState);
4243 PyInterpreterState_Delete(pInterpreterState);
4244#endif
4245
Fredrik Lundh56055a42000-07-23 19:47:12 +00004246 return result;
4247}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004248
4249#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004251posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004252{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004253 char *name;
4254 char *mode = "r";
4255 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004256 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004257 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004258 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004259 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004260 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004261 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004262 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004263 if (fp == NULL)
4264 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004265 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004266 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004267 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004268 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004269}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004270
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004271#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004272#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004274
Guido van Rossumb6775db1994-08-01 11:34:53 +00004275#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004276PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004277"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004278Set the current process's user id.");
4279
Barry Warsaw53699e91996-12-10 23:23:01 +00004280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004281posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004282{
4283 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004284 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004285 return NULL;
4286 if (setuid(uid) < 0)
4287 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004288 Py_INCREF(Py_None);
4289 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004290}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004291#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004293
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004294#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004295PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004296"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004297Set the current process's effective user id.");
4298
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004299static PyObject *
4300posix_seteuid (PyObject *self, PyObject *args)
4301{
4302 int euid;
4303 if (!PyArg_ParseTuple(args, "i", &euid)) {
4304 return NULL;
4305 } else if (seteuid(euid) < 0) {
4306 return posix_error();
4307 } else {
4308 Py_INCREF(Py_None);
4309 return Py_None;
4310 }
4311}
4312#endif /* HAVE_SETEUID */
4313
4314#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004315PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004316"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004317Set the current process's effective group id.");
4318
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004319static PyObject *
4320posix_setegid (PyObject *self, PyObject *args)
4321{
4322 int egid;
4323 if (!PyArg_ParseTuple(args, "i", &egid)) {
4324 return NULL;
4325 } else if (setegid(egid) < 0) {
4326 return posix_error();
4327 } else {
4328 Py_INCREF(Py_None);
4329 return Py_None;
4330 }
4331}
4332#endif /* HAVE_SETEGID */
4333
4334#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004335PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004336"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004337Set the current process's real and effective user ids.");
4338
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004339static PyObject *
4340posix_setreuid (PyObject *self, PyObject *args)
4341{
4342 int ruid, euid;
4343 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4344 return NULL;
4345 } else if (setreuid(ruid, euid) < 0) {
4346 return posix_error();
4347 } else {
4348 Py_INCREF(Py_None);
4349 return Py_None;
4350 }
4351}
4352#endif /* HAVE_SETREUID */
4353
4354#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004355PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004356"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004357Set the current process's real and effective group ids.");
4358
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004359static PyObject *
4360posix_setregid (PyObject *self, PyObject *args)
4361{
4362 int rgid, egid;
4363 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4364 return NULL;
4365 } else if (setregid(rgid, egid) < 0) {
4366 return posix_error();
4367 } else {
4368 Py_INCREF(Py_None);
4369 return Py_None;
4370 }
4371}
4372#endif /* HAVE_SETREGID */
4373
Guido van Rossumb6775db1994-08-01 11:34:53 +00004374#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004375PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004376"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004377Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004378
Barry Warsaw53699e91996-12-10 23:23:01 +00004379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004380posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004381{
4382 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004383 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004384 return NULL;
4385 if (setgid(gid) < 0)
4386 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004387 Py_INCREF(Py_None);
4388 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004389}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004390#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004391
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004392#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004393PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004394"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004395Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004396
4397static PyObject *
4398posix_setgroups(PyObject *self, PyObject *args)
4399{
4400 PyObject *groups;
4401 int i, len;
4402 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004403
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004404 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4405 return NULL;
4406 if (!PySequence_Check(groups)) {
4407 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4408 return NULL;
4409 }
4410 len = PySequence_Size(groups);
4411 if (len > MAX_GROUPS) {
4412 PyErr_SetString(PyExc_ValueError, "too many groups");
4413 return NULL;
4414 }
4415 for(i = 0; i < len; i++) {
4416 PyObject *elem;
4417 elem = PySequence_GetItem(groups, i);
4418 if (!elem)
4419 return NULL;
4420 if (!PyInt_Check(elem)) {
4421 PyErr_SetString(PyExc_TypeError,
4422 "groups must be integers");
4423 Py_DECREF(elem);
4424 return NULL;
4425 }
4426 /* XXX: check that value fits into gid_t. */
4427 grouplist[i] = PyInt_AsLong(elem);
4428 Py_DECREF(elem);
4429 }
4430
4431 if (setgroups(len, grouplist) < 0)
4432 return posix_error();
4433 Py_INCREF(Py_None);
4434 return Py_None;
4435}
4436#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004437
Guido van Rossumb6775db1994-08-01 11:34:53 +00004438#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004439PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004440"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004441Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004442
Barry Warsaw53699e91996-12-10 23:23:01 +00004443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004444posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004445{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004446 int pid, options;
4447#ifdef UNION_WAIT
4448 union wait status;
4449#define status_i (status.w_status)
4450#else
4451 int status;
4452#define status_i status
4453#endif
4454 status_i = 0;
4455
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004456 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004457 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004458 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004459 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004460 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004461 if (pid == -1)
4462 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004463 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004464 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004465}
4466
Tim Petersab034fa2002-02-01 11:27:43 +00004467#elif defined(HAVE_CWAIT)
4468
4469/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004470PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004471"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004472"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004473
4474static PyObject *
4475posix_waitpid(PyObject *self, PyObject *args)
4476{
4477 int pid, options;
4478 int status;
4479
4480 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4481 return NULL;
4482 Py_BEGIN_ALLOW_THREADS
4483 pid = _cwait(&status, pid, options);
4484 Py_END_ALLOW_THREADS
4485 if (pid == -1)
4486 return posix_error();
4487 else
4488 /* shift the status left a byte so this is more like the
4489 POSIX waitpid */
4490 return Py_BuildValue("ii", pid, status << 8);
4491}
4492#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004493
Guido van Rossumad0ee831995-03-01 10:34:45 +00004494#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004495PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004496"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004497Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004498
Barry Warsaw53699e91996-12-10 23:23:01 +00004499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004500posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004501{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004502 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004503#ifdef UNION_WAIT
4504 union wait status;
4505#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004506#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004507 int status;
4508#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004509#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004510 if (!PyArg_ParseTuple(args, ":wait"))
4511 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004512 status_i = 0;
4513 Py_BEGIN_ALLOW_THREADS
4514 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004515 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004516 if (pid == -1)
4517 return posix_error();
4518 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004519 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004520#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004521}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004522#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004525PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004526"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004527Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004528
Barry Warsaw53699e91996-12-10 23:23:01 +00004529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004530posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004531{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004532#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004533 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004534#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004535#ifdef MS_WINDOWS
4536 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4537#else
4538 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4539#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004540#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004541}
4542
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004543
Guido van Rossumb6775db1994-08-01 11:34:53 +00004544#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004545PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004546"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004547Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004548
Barry Warsaw53699e91996-12-10 23:23:01 +00004549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004550posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004551{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004552 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004553 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004554 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004555 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004556 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004557 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004558 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004559 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004560 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004561 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004562 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004563}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004564#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004566
Guido van Rossumb6775db1994-08-01 11:34:53 +00004567#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004568PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004569"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004570Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004571
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004572static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004573posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004574{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004575 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004576}
4577#endif /* HAVE_SYMLINK */
4578
4579
4580#ifdef HAVE_TIMES
4581#ifndef HZ
4582#define HZ 60 /* Universal constant :-) */
4583#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004584
Guido van Rossumd48f2521997-12-05 22:19:34 +00004585#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4586static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004587system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004588{
4589 ULONG value = 0;
4590
4591 Py_BEGIN_ALLOW_THREADS
4592 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4593 Py_END_ALLOW_THREADS
4594
4595 return value;
4596}
4597
4598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004599posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004600{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004601 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004602 return NULL;
4603
4604 /* Currently Only Uptime is Provided -- Others Later */
4605 return Py_BuildValue("ddddd",
4606 (double)0 /* t.tms_utime / HZ */,
4607 (double)0 /* t.tms_stime / HZ */,
4608 (double)0 /* t.tms_cutime / HZ */,
4609 (double)0 /* t.tms_cstime / HZ */,
4610 (double)system_uptime() / 1000);
4611}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004612#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004613static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004614posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004615{
4616 struct tms t;
4617 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004618 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004619 return NULL;
4620 errno = 0;
4621 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004622 if (c == (clock_t) -1)
4623 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004624 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004625 (double)t.tms_utime / HZ,
4626 (double)t.tms_stime / HZ,
4627 (double)t.tms_cutime / HZ,
4628 (double)t.tms_cstime / HZ,
4629 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004630}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004631#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004632#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004633
4634
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004635#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004636#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004638posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004639{
4640 FILETIME create, exit, kernel, user;
4641 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004642 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004643 return NULL;
4644 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004645 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4646 /* The fields of a FILETIME structure are the hi and lo part
4647 of a 64-bit value expressed in 100 nanosecond units.
4648 1e7 is one second in such units; 1e-7 the inverse.
4649 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4650 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004651 return Py_BuildValue(
4652 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004653 (double)(kernel.dwHighDateTime*429.4967296 +
4654 kernel.dwLowDateTime*1e-7),
4655 (double)(user.dwHighDateTime*429.4967296 +
4656 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004657 (double)0,
4658 (double)0,
4659 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004660}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004661#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004662
4663#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004664PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004665"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004666Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004667#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004669
Guido van Rossumb6775db1994-08-01 11:34:53 +00004670#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004671PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004672"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004673Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004674
Barry Warsaw53699e91996-12-10 23:23:01 +00004675static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004676posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004677{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004678 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004679 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004680 if (setsid() < 0)
4681 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004682 Py_INCREF(Py_None);
4683 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004684}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004685#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004686
Guido van Rossumb6775db1994-08-01 11:34:53 +00004687#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004688PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004689"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004690Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004691
Barry Warsaw53699e91996-12-10 23:23:01 +00004692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004693posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004694{
4695 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004696 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004697 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004698 if (setpgid(pid, pgrp) < 0)
4699 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004700 Py_INCREF(Py_None);
4701 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004702}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004703#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004704
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004705
Guido van Rossumb6775db1994-08-01 11:34:53 +00004706#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004707PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004708"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004709Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004710
Barry Warsaw53699e91996-12-10 23:23:01 +00004711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004712posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004713{
4714 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004715 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004716 return NULL;
4717 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004718 if (pgid < 0)
4719 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004720 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004721}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004722#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004724
Guido van Rossumb6775db1994-08-01 11:34:53 +00004725#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004726PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004727"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004728Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004729
Barry Warsaw53699e91996-12-10 23:23:01 +00004730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004731posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004732{
4733 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004734 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004735 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004736 if (tcsetpgrp(fd, pgid) < 0)
4737 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004738 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004739 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004740}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004741#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004742
Guido van Rossum687dd131993-05-17 08:34:16 +00004743/* Functions acting on file descriptors */
4744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004745PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004746"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004747Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004748
Barry Warsaw53699e91996-12-10 23:23:01 +00004749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004750posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004751{
Mark Hammondef8b6542001-05-13 08:04:26 +00004752 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004753 int flag;
4754 int mode = 0777;
4755 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004756
4757#ifdef MS_WINDOWS
4758 if (unicode_file_names()) {
4759 PyUnicodeObject *po;
4760 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4761 Py_BEGIN_ALLOW_THREADS
4762 /* PyUnicode_AS_UNICODE OK without thread
4763 lock as it is a simple dereference. */
4764 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4765 Py_END_ALLOW_THREADS
4766 if (fd < 0)
4767 return posix_error();
4768 return PyInt_FromLong((long)fd);
4769 }
4770 /* Drop the argument parsing error as narrow strings
4771 are also valid. */
4772 PyErr_Clear();
4773 }
4774#endif
4775
Tim Peters5aa91602002-01-30 05:46:57 +00004776 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004777 Py_FileSystemDefaultEncoding, &file,
4778 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004779 return NULL;
4780
Barry Warsaw53699e91996-12-10 23:23:01 +00004781 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004782 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004783 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004784 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004785 return posix_error_with_allocated_filename(file);
4786 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004787 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004788}
4789
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004790
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004791PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004792"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004793Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004794
Barry Warsaw53699e91996-12-10 23:23:01 +00004795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004796posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004797{
4798 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004799 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004800 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004801 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004802 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004803 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004804 if (res < 0)
4805 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004806 Py_INCREF(Py_None);
4807 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004808}
4809
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004810
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004811PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004812"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004813Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004814
Barry Warsaw53699e91996-12-10 23:23:01 +00004815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004816posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004817{
4818 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004819 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004820 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004821 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004822 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004823 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004824 if (fd < 0)
4825 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004826 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004827}
4828
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004829
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004830PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004831"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004832Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004833
Barry Warsaw53699e91996-12-10 23:23:01 +00004834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004835posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004836{
4837 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004838 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004839 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004840 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004841 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004842 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004843 if (res < 0)
4844 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004845 Py_INCREF(Py_None);
4846 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004847}
4848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004849
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004850PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004851"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004852Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004853
Barry Warsaw53699e91996-12-10 23:23:01 +00004854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004855posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004856{
4857 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004858#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004859 LONG_LONG pos, res;
4860#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004861 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004862#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004863 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004864 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004865 return NULL;
4866#ifdef SEEK_SET
4867 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4868 switch (how) {
4869 case 0: how = SEEK_SET; break;
4870 case 1: how = SEEK_CUR; break;
4871 case 2: how = SEEK_END; break;
4872 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004873#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004874
4875#if !defined(HAVE_LARGEFILE_SUPPORT)
4876 pos = PyInt_AsLong(posobj);
4877#else
4878 pos = PyLong_Check(posobj) ?
4879 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4880#endif
4881 if (PyErr_Occurred())
4882 return NULL;
4883
Barry Warsaw53699e91996-12-10 23:23:01 +00004884 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004885#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004886 res = _lseeki64(fd, pos, how);
4887#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004888 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004889#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004890 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004891 if (res < 0)
4892 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004893
4894#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004895 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004896#else
4897 return PyLong_FromLongLong(res);
4898#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004899}
4900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004901
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004902PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004903"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004904Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004905
Barry Warsaw53699e91996-12-10 23:23:01 +00004906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004907posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004908{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004909 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004910 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004911 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004912 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004913 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004914 if (buffer == NULL)
4915 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004916 Py_BEGIN_ALLOW_THREADS
4917 n = read(fd, PyString_AsString(buffer), size);
4918 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004919 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004920 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004921 return posix_error();
4922 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004923 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004924 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004925 return buffer;
4926}
4927
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004928
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004929PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004930"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004931Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Barry Warsaw53699e91996-12-10 23:23:01 +00004933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004934posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004935{
4936 int fd, size;
4937 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004938 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004939 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004940 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004941 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004942 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004943 if (size < 0)
4944 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004945 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004946}
4947
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004948
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004949PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004950"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004951Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004952
Barry Warsaw53699e91996-12-10 23:23:01 +00004953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004954posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004955{
4956 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004957 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004958 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004959 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004960 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004961 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004962 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004963 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004964 if (res != 0)
4965 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004966
Fred Drake699f3522000-06-29 21:12:41 +00004967 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004968}
4969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004971PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004972"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004973Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004974
Barry Warsaw53699e91996-12-10 23:23:01 +00004975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004976posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004977{
Guido van Rossum687dd131993-05-17 08:34:16 +00004978 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004979 char *mode = "r";
4980 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004981 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004982 PyObject *f;
4983 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004984 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004985
Barry Warsaw53699e91996-12-10 23:23:01 +00004986 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004987 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004988 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004989 if (fp == NULL)
4990 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00004991 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004992 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004993 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004994 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004995}
4996
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004997PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004998"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004999Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005000connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005001
5002static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005003posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005004{
5005 int fd;
5006 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5007 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005008 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005009}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005010
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005011#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005012PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005013"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005015
Barry Warsaw53699e91996-12-10 23:23:01 +00005016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005017posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005018{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005019#if defined(PYOS_OS2)
5020 HFILE read, write;
5021 APIRET rc;
5022
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005023 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005024 return NULL;
5025
5026 Py_BEGIN_ALLOW_THREADS
5027 rc = DosCreatePipe( &read, &write, 4096);
5028 Py_END_ALLOW_THREADS
5029 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005030 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005031
5032 return Py_BuildValue("(ii)", read, write);
5033#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005034#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005035 int fds[2];
5036 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005037 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00005038 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005039 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005040 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005041 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005042 if (res != 0)
5043 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005044 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005045#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005046 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005047 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005048 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005049 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00005050 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005051 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005052 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005053 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005054 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005055 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005056 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5057 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005058 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005059#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005060#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005061}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005062#endif /* HAVE_PIPE */
5063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005064
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005065#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005066PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005067"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005068Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005069
Barry Warsaw53699e91996-12-10 23:23:01 +00005070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005071posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005072{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005073 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005074 int mode = 0666;
5075 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005076 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005077 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005078 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005079 res = mkfifo(filename, mode);
5080 Py_END_ALLOW_THREADS
5081 if (res < 0)
5082 return posix_error();
5083 Py_INCREF(Py_None);
5084 return Py_None;
5085}
5086#endif
5087
5088
Neal Norwitz11690112002-07-30 01:08:28 +00005089#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005090PyDoc_STRVAR(posix_mknod__doc__,
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005091"mknod(filename, [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005092Create a filesystem node (file, device special file or named pipe)\n\
5093named filename. mode specifies both the permissions to use and the\n\
5094type of node to be created, being combined (bitwise OR) with one of\n\
5095S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005096device defines the newly created device special file (probably using\n\
5097os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005098
5099
5100static PyObject *
5101posix_mknod(PyObject *self, PyObject *args)
5102{
5103 char *filename;
5104 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005105 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005106 int res;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005107 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005108 return NULL;
5109 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005110 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005111 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005112 if (res < 0)
5113 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005114 Py_INCREF(Py_None);
5115 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005116}
5117#endif
5118
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005119#ifdef HAVE_DEVICE_MACROS
5120PyDoc_STRVAR(posix_major__doc__,
5121"major(device) -> major number\n\
5122Extracts a device major number from a raw device number.");
5123
5124static PyObject *
5125posix_major(PyObject *self, PyObject *args)
5126{
5127 int device;
5128 if (!PyArg_ParseTuple(args, "i:major", &device))
5129 return NULL;
5130 return PyInt_FromLong((long)major(device));
5131}
5132
5133PyDoc_STRVAR(posix_minor__doc__,
5134"minor(device) -> minor number\n\
5135Extracts a device minor number from a raw device number.");
5136
5137static PyObject *
5138posix_minor(PyObject *self, PyObject *args)
5139{
5140 int device;
5141 if (!PyArg_ParseTuple(args, "i:minor", &device))
5142 return NULL;
5143 return PyInt_FromLong((long)minor(device));
5144}
5145
5146PyDoc_STRVAR(posix_makedev__doc__,
5147"makedev(major, minor) -> device number\n\
5148Composes a raw device number from the major and minor device numbers.");
5149
5150static PyObject *
5151posix_makedev(PyObject *self, PyObject *args)
5152{
5153 int major, minor;
5154 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5155 return NULL;
5156 return PyInt_FromLong((long)makedev(major, minor));
5157}
5158#endif /* device macros */
5159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005160
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005161#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005162PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005163"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005164Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005165
Barry Warsaw53699e91996-12-10 23:23:01 +00005166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005167posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005168{
5169 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005170 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005171 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005172 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005173
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005174 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005175 return NULL;
5176
5177#if !defined(HAVE_LARGEFILE_SUPPORT)
5178 length = PyInt_AsLong(lenobj);
5179#else
5180 length = PyLong_Check(lenobj) ?
5181 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5182#endif
5183 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005184 return NULL;
5185
Barry Warsaw53699e91996-12-10 23:23:01 +00005186 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005187 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005188 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005189 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005190 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005191 return NULL;
5192 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005193 Py_INCREF(Py_None);
5194 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005195}
5196#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005197
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005198#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005199PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005200"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005201Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005202
Fred Drake762e2061999-08-26 17:23:54 +00005203/* Save putenv() parameters as values here, so we can collect them when they
5204 * get re-set with another call for the same key. */
5205static PyObject *posix_putenv_garbage;
5206
Tim Peters5aa91602002-01-30 05:46:57 +00005207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005208posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005209{
5210 char *s1, *s2;
5211 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005212 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005213 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005214
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005215 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005216 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005217
5218#if defined(PYOS_OS2)
5219 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5220 APIRET rc;
5221
5222 if (strlen(s2) == 0) /* If New Value is an Empty String */
5223 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5224
5225 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5226 if (rc != NO_ERROR)
5227 return os2_error(rc);
5228
5229 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5230 APIRET rc;
5231
5232 if (strlen(s2) == 0) /* If New Value is an Empty String */
5233 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5234
5235 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5236 if (rc != NO_ERROR)
5237 return os2_error(rc);
5238 } else {
5239#endif
5240
Fred Drake762e2061999-08-26 17:23:54 +00005241 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005242 len = strlen(s1) + strlen(s2) + 2;
5243 /* len includes space for a trailing \0; the size arg to
5244 PyString_FromStringAndSize does not count that */
5245 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005246 if (newstr == NULL)
5247 return PyErr_NoMemory();
5248 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005249 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005250 if (putenv(new)) {
5251 posix_error();
5252 return NULL;
5253 }
Fred Drake762e2061999-08-26 17:23:54 +00005254 /* Install the first arg and newstr in posix_putenv_garbage;
5255 * this will cause previous value to be collected. This has to
5256 * happen after the real putenv() call because the old value
5257 * was still accessible until then. */
5258 if (PyDict_SetItem(posix_putenv_garbage,
5259 PyTuple_GET_ITEM(args, 0), newstr)) {
5260 /* really not much we can do; just leak */
5261 PyErr_Clear();
5262 }
5263 else {
5264 Py_DECREF(newstr);
5265 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005266
5267#if defined(PYOS_OS2)
5268 }
5269#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005270 Py_INCREF(Py_None);
5271 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005272}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005273#endif /* putenv */
5274
Guido van Rossumc524d952001-10-19 01:31:59 +00005275#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005276PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005277"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005278Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005279
5280static PyObject *
5281posix_unsetenv(PyObject *self, PyObject *args)
5282{
5283 char *s1;
5284
5285 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5286 return NULL;
5287
5288 unsetenv(s1);
5289
5290 /* Remove the key from posix_putenv_garbage;
5291 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005292 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005293 * old value was still accessible until then.
5294 */
5295 if (PyDict_DelItem(posix_putenv_garbage,
5296 PyTuple_GET_ITEM(args, 0))) {
5297 /* really not much we can do; just leak */
5298 PyErr_Clear();
5299 }
5300
5301 Py_INCREF(Py_None);
5302 return Py_None;
5303}
5304#endif /* unsetenv */
5305
Guido van Rossumb6a47161997-09-15 22:54:34 +00005306#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005307PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005308"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005309Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005310
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005312posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005313{
5314 int code;
5315 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005316 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005317 return NULL;
5318 message = strerror(code);
5319 if (message == NULL) {
5320 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005321 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005322 return NULL;
5323 }
5324 return PyString_FromString(message);
5325}
5326#endif /* strerror */
5327
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005328
Guido van Rossumc9641791998-08-04 15:26:23 +00005329#ifdef HAVE_SYS_WAIT_H
5330
Fred Drake106c1a02002-04-23 15:58:02 +00005331#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005332PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005333"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005334Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005335
5336static PyObject *
5337posix_WCOREDUMP(PyObject *self, PyObject *args)
5338{
5339#ifdef UNION_WAIT
5340 union wait status;
5341#define status_i (status.w_status)
5342#else
5343 int status;
5344#define status_i status
5345#endif
5346 status_i = 0;
5347
5348 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5349 {
5350 return NULL;
5351 }
5352
5353 return PyBool_FromLong(WCOREDUMP(status));
5354#undef status_i
5355}
5356#endif /* WCOREDUMP */
5357
5358#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005359PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005360"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005361Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005363
5364static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005365posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005366{
5367#ifdef UNION_WAIT
5368 union wait status;
5369#define status_i (status.w_status)
5370#else
5371 int status;
5372#define status_i status
5373#endif
5374 status_i = 0;
5375
5376 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5377 {
5378 return NULL;
5379 }
5380
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005381 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005382#undef status_i
5383}
5384#endif /* WIFCONTINUED */
5385
Guido van Rossumc9641791998-08-04 15:26:23 +00005386#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005387PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005388"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005389Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005390
5391static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005392posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005393{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005394#ifdef UNION_WAIT
5395 union wait status;
5396#define status_i (status.w_status)
5397#else
5398 int status;
5399#define status_i status
5400#endif
5401 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005402
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005403 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005404 {
5405 return NULL;
5406 }
Tim Peters5aa91602002-01-30 05:46:57 +00005407
Fred Drake106c1a02002-04-23 15:58:02 +00005408 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005409#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005410}
5411#endif /* WIFSTOPPED */
5412
5413#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005414PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005415"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005416Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005417
5418static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005419posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005420{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005421#ifdef UNION_WAIT
5422 union wait status;
5423#define status_i (status.w_status)
5424#else
5425 int status;
5426#define status_i status
5427#endif
5428 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005429
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005430 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005431 {
5432 return NULL;
5433 }
Tim Peters5aa91602002-01-30 05:46:57 +00005434
Fred Drake106c1a02002-04-23 15:58:02 +00005435 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005436#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005437}
5438#endif /* WIFSIGNALED */
5439
5440#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005441PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005442"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005443Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005444system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005445
5446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005447posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005448{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005449#ifdef UNION_WAIT
5450 union wait status;
5451#define status_i (status.w_status)
5452#else
5453 int status;
5454#define status_i status
5455#endif
5456 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005457
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005458 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005459 {
5460 return NULL;
5461 }
Tim Peters5aa91602002-01-30 05:46:57 +00005462
Fred Drake106c1a02002-04-23 15:58:02 +00005463 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005464#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005465}
5466#endif /* WIFEXITED */
5467
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005468#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005469PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005470"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005471Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005472
5473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005474posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005475{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005476#ifdef UNION_WAIT
5477 union wait status;
5478#define status_i (status.w_status)
5479#else
5480 int status;
5481#define status_i status
5482#endif
5483 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005484
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005485 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005486 {
5487 return NULL;
5488 }
Tim Peters5aa91602002-01-30 05:46:57 +00005489
Guido van Rossumc9641791998-08-04 15:26:23 +00005490 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005491#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005492}
5493#endif /* WEXITSTATUS */
5494
5495#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005496PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005497"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005498Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005499value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005500
5501static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005502posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005503{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005504#ifdef UNION_WAIT
5505 union wait status;
5506#define status_i (status.w_status)
5507#else
5508 int status;
5509#define status_i status
5510#endif
5511 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005512
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005513 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005514 {
5515 return NULL;
5516 }
Tim Peters5aa91602002-01-30 05:46:57 +00005517
Guido van Rossumc9641791998-08-04 15:26:23 +00005518 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005519#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005520}
5521#endif /* WTERMSIG */
5522
5523#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005524PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005525"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005526Return the signal that stopped the process that provided\n\
5527the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005528
5529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005530posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005531{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005532#ifdef UNION_WAIT
5533 union wait status;
5534#define status_i (status.w_status)
5535#else
5536 int status;
5537#define status_i status
5538#endif
5539 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005540
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005541 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005542 {
5543 return NULL;
5544 }
Tim Peters5aa91602002-01-30 05:46:57 +00005545
Guido van Rossumc9641791998-08-04 15:26:23 +00005546 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005547#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005548}
5549#endif /* WSTOPSIG */
5550
5551#endif /* HAVE_SYS_WAIT_H */
5552
5553
Guido van Rossum94f6f721999-01-06 18:42:14 +00005554#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005555#ifdef _SCO_DS
5556/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5557 needed definitions in sys/statvfs.h */
5558#define _SVID3
5559#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005560#include <sys/statvfs.h>
5561
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005562static PyObject*
5563_pystatvfs_fromstructstatvfs(struct statvfs st) {
5564 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5565 if (v == NULL)
5566 return NULL;
5567
5568#if !defined(HAVE_LARGEFILE_SUPPORT)
5569 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5570 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5571 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5572 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5573 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5574 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5575 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5576 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5577 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5578 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5579#else
5580 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5581 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005582 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005583 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005584 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005585 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5586 PyStructSequence_SET_ITEM(v, 4,
5587 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005588 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005589 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005590 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005591 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005592 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005593 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5594 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5595 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5596#endif
5597
5598 return v;
5599}
5600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005601PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005602"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005603Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005604
5605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005606posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005607{
5608 int fd, res;
5609 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005610
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005611 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005612 return NULL;
5613 Py_BEGIN_ALLOW_THREADS
5614 res = fstatvfs(fd, &st);
5615 Py_END_ALLOW_THREADS
5616 if (res != 0)
5617 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005618
5619 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005620}
5621#endif /* HAVE_FSTATVFS */
5622
5623
5624#if defined(HAVE_STATVFS)
5625#include <sys/statvfs.h>
5626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005627PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005628"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005629Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005630
5631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005632posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005633{
5634 char *path;
5635 int res;
5636 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005637 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005638 return NULL;
5639 Py_BEGIN_ALLOW_THREADS
5640 res = statvfs(path, &st);
5641 Py_END_ALLOW_THREADS
5642 if (res != 0)
5643 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005644
5645 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005646}
5647#endif /* HAVE_STATVFS */
5648
5649
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005650#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005651PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005652"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005653Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005654The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005655or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005656
5657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005658posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005659{
5660 PyObject *result = NULL;
5661 char *dir = NULL;
5662 char *pfx = NULL;
5663 char *name;
5664
5665 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5666 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005667
5668 if (PyErr_Warn(PyExc_RuntimeWarning,
5669 "tempnam is a potential security risk to your program") < 0)
5670 return NULL;
5671
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005672#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005673 name = _tempnam(dir, pfx);
5674#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005675 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005676#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005677 if (name == NULL)
5678 return PyErr_NoMemory();
5679 result = PyString_FromString(name);
5680 free(name);
5681 return result;
5682}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005683#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005684
5685
5686#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005687PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005688"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005689Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005690
5691static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005692posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005693{
5694 FILE *fp;
5695
5696 if (!PyArg_ParseTuple(args, ":tmpfile"))
5697 return NULL;
5698 fp = tmpfile();
5699 if (fp == NULL)
5700 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005701 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005702}
5703#endif
5704
5705
5706#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005707PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005708"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005709Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005710
5711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005712posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005713{
5714 char buffer[L_tmpnam];
5715 char *name;
5716
5717 if (!PyArg_ParseTuple(args, ":tmpnam"))
5718 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005719
5720 if (PyErr_Warn(PyExc_RuntimeWarning,
5721 "tmpnam is a potential security risk to your program") < 0)
5722 return NULL;
5723
Greg Wardb48bc172000-03-01 21:51:56 +00005724#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005725 name = tmpnam_r(buffer);
5726#else
5727 name = tmpnam(buffer);
5728#endif
5729 if (name == NULL) {
5730 PyErr_SetObject(PyExc_OSError,
5731 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005732#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005733 "unexpected NULL from tmpnam_r"
5734#else
5735 "unexpected NULL from tmpnam"
5736#endif
5737 ));
5738 return NULL;
5739 }
5740 return PyString_FromString(buffer);
5741}
5742#endif
5743
5744
Fred Drakec9680921999-12-13 16:37:25 +00005745/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5746 * It maps strings representing configuration variable names to
5747 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005748 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005749 * rarely-used constants. There are three separate tables that use
5750 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005751 *
5752 * This code is always included, even if none of the interfaces that
5753 * need it are included. The #if hackery needed to avoid it would be
5754 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005755 */
5756struct constdef {
5757 char *name;
5758 long value;
5759};
5760
Fred Drake12c6e2d1999-12-14 21:25:03 +00005761static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005762conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5763 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005764{
5765 if (PyInt_Check(arg)) {
5766 *valuep = PyInt_AS_LONG(arg);
5767 return 1;
5768 }
5769 if (PyString_Check(arg)) {
5770 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005771 size_t lo = 0;
5772 size_t mid;
5773 size_t hi = tablesize;
5774 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005775 char *confname = PyString_AS_STRING(arg);
5776 while (lo < hi) {
5777 mid = (lo + hi) / 2;
5778 cmp = strcmp(confname, table[mid].name);
5779 if (cmp < 0)
5780 hi = mid;
5781 else if (cmp > 0)
5782 lo = mid + 1;
5783 else {
5784 *valuep = table[mid].value;
5785 return 1;
5786 }
5787 }
5788 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5789 }
5790 else
5791 PyErr_SetString(PyExc_TypeError,
5792 "configuration names must be strings or integers");
5793 return 0;
5794}
5795
5796
5797#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5798static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005799#ifdef _PC_ABI_AIO_XFER_MAX
5800 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5801#endif
5802#ifdef _PC_ABI_ASYNC_IO
5803 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5804#endif
Fred Drakec9680921999-12-13 16:37:25 +00005805#ifdef _PC_ASYNC_IO
5806 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5807#endif
5808#ifdef _PC_CHOWN_RESTRICTED
5809 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5810#endif
5811#ifdef _PC_FILESIZEBITS
5812 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5813#endif
5814#ifdef _PC_LAST
5815 {"PC_LAST", _PC_LAST},
5816#endif
5817#ifdef _PC_LINK_MAX
5818 {"PC_LINK_MAX", _PC_LINK_MAX},
5819#endif
5820#ifdef _PC_MAX_CANON
5821 {"PC_MAX_CANON", _PC_MAX_CANON},
5822#endif
5823#ifdef _PC_MAX_INPUT
5824 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5825#endif
5826#ifdef _PC_NAME_MAX
5827 {"PC_NAME_MAX", _PC_NAME_MAX},
5828#endif
5829#ifdef _PC_NO_TRUNC
5830 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5831#endif
5832#ifdef _PC_PATH_MAX
5833 {"PC_PATH_MAX", _PC_PATH_MAX},
5834#endif
5835#ifdef _PC_PIPE_BUF
5836 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5837#endif
5838#ifdef _PC_PRIO_IO
5839 {"PC_PRIO_IO", _PC_PRIO_IO},
5840#endif
5841#ifdef _PC_SOCK_MAXBUF
5842 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5843#endif
5844#ifdef _PC_SYNC_IO
5845 {"PC_SYNC_IO", _PC_SYNC_IO},
5846#endif
5847#ifdef _PC_VDISABLE
5848 {"PC_VDISABLE", _PC_VDISABLE},
5849#endif
5850};
5851
Fred Drakec9680921999-12-13 16:37:25 +00005852static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005853conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005854{
5855 return conv_confname(arg, valuep, posix_constants_pathconf,
5856 sizeof(posix_constants_pathconf)
5857 / sizeof(struct constdef));
5858}
5859#endif
5860
5861#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005862PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005863"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005864Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005865If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005866
5867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005868posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005869{
5870 PyObject *result = NULL;
5871 int name, fd;
5872
Fred Drake12c6e2d1999-12-14 21:25:03 +00005873 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5874 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005875 long limit;
5876
5877 errno = 0;
5878 limit = fpathconf(fd, name);
5879 if (limit == -1 && errno != 0)
5880 posix_error();
5881 else
5882 result = PyInt_FromLong(limit);
5883 }
5884 return result;
5885}
5886#endif
5887
5888
5889#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005890PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005891"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005892Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005893If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005894
5895static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005896posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005897{
5898 PyObject *result = NULL;
5899 int name;
5900 char *path;
5901
5902 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5903 conv_path_confname, &name)) {
5904 long limit;
5905
5906 errno = 0;
5907 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005908 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005909 if (errno == EINVAL)
5910 /* could be a path or name problem */
5911 posix_error();
5912 else
5913 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005914 }
Fred Drakec9680921999-12-13 16:37:25 +00005915 else
5916 result = PyInt_FromLong(limit);
5917 }
5918 return result;
5919}
5920#endif
5921
5922#ifdef HAVE_CONFSTR
5923static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005924#ifdef _CS_ARCHITECTURE
5925 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5926#endif
5927#ifdef _CS_HOSTNAME
5928 {"CS_HOSTNAME", _CS_HOSTNAME},
5929#endif
5930#ifdef _CS_HW_PROVIDER
5931 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5932#endif
5933#ifdef _CS_HW_SERIAL
5934 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5935#endif
5936#ifdef _CS_INITTAB_NAME
5937 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5938#endif
Fred Drakec9680921999-12-13 16:37:25 +00005939#ifdef _CS_LFS64_CFLAGS
5940 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5941#endif
5942#ifdef _CS_LFS64_LDFLAGS
5943 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5944#endif
5945#ifdef _CS_LFS64_LIBS
5946 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5947#endif
5948#ifdef _CS_LFS64_LINTFLAGS
5949 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5950#endif
5951#ifdef _CS_LFS_CFLAGS
5952 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5953#endif
5954#ifdef _CS_LFS_LDFLAGS
5955 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5956#endif
5957#ifdef _CS_LFS_LIBS
5958 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5959#endif
5960#ifdef _CS_LFS_LINTFLAGS
5961 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5962#endif
Fred Draked86ed291999-12-15 15:34:33 +00005963#ifdef _CS_MACHINE
5964 {"CS_MACHINE", _CS_MACHINE},
5965#endif
Fred Drakec9680921999-12-13 16:37:25 +00005966#ifdef _CS_PATH
5967 {"CS_PATH", _CS_PATH},
5968#endif
Fred Draked86ed291999-12-15 15:34:33 +00005969#ifdef _CS_RELEASE
5970 {"CS_RELEASE", _CS_RELEASE},
5971#endif
5972#ifdef _CS_SRPC_DOMAIN
5973 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5974#endif
5975#ifdef _CS_SYSNAME
5976 {"CS_SYSNAME", _CS_SYSNAME},
5977#endif
5978#ifdef _CS_VERSION
5979 {"CS_VERSION", _CS_VERSION},
5980#endif
Fred Drakec9680921999-12-13 16:37:25 +00005981#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5982 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5983#endif
5984#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5985 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5986#endif
5987#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5988 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5989#endif
5990#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5991 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5992#endif
5993#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5994 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5995#endif
5996#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5997 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5998#endif
5999#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6000 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6001#endif
6002#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6003 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6004#endif
6005#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6006 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6007#endif
6008#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6009 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6010#endif
6011#ifdef _CS_XBS5_LP64_OFF64_LIBS
6012 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6013#endif
6014#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6015 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6016#endif
6017#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6018 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6019#endif
6020#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6021 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6022#endif
6023#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6024 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6025#endif
6026#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6027 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6028#endif
Fred Draked86ed291999-12-15 15:34:33 +00006029#ifdef _MIPS_CS_AVAIL_PROCESSORS
6030 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6031#endif
6032#ifdef _MIPS_CS_BASE
6033 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6034#endif
6035#ifdef _MIPS_CS_HOSTID
6036 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6037#endif
6038#ifdef _MIPS_CS_HW_NAME
6039 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6040#endif
6041#ifdef _MIPS_CS_NUM_PROCESSORS
6042 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6043#endif
6044#ifdef _MIPS_CS_OSREL_MAJ
6045 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6046#endif
6047#ifdef _MIPS_CS_OSREL_MIN
6048 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6049#endif
6050#ifdef _MIPS_CS_OSREL_PATCH
6051 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6052#endif
6053#ifdef _MIPS_CS_OS_NAME
6054 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6055#endif
6056#ifdef _MIPS_CS_OS_PROVIDER
6057 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6058#endif
6059#ifdef _MIPS_CS_PROCESSORS
6060 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6061#endif
6062#ifdef _MIPS_CS_SERIAL
6063 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6064#endif
6065#ifdef _MIPS_CS_VENDOR
6066 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6067#endif
Fred Drakec9680921999-12-13 16:37:25 +00006068};
6069
6070static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006071conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006072{
6073 return conv_confname(arg, valuep, posix_constants_confstr,
6074 sizeof(posix_constants_confstr)
6075 / sizeof(struct constdef));
6076}
6077
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006078PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006079"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006081
6082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006083posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006084{
6085 PyObject *result = NULL;
6086 int name;
6087 char buffer[64];
6088
6089 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6090 int len = confstr(name, buffer, sizeof(buffer));
6091
Fred Drakec9680921999-12-13 16:37:25 +00006092 errno = 0;
6093 if (len == 0) {
6094 if (errno != 0)
6095 posix_error();
6096 else
6097 result = PyString_FromString("");
6098 }
6099 else {
6100 if (len >= sizeof(buffer)) {
6101 result = PyString_FromStringAndSize(NULL, len);
6102 if (result != NULL)
6103 confstr(name, PyString_AS_STRING(result), len+1);
6104 }
6105 else
6106 result = PyString_FromString(buffer);
6107 }
6108 }
6109 return result;
6110}
6111#endif
6112
6113
6114#ifdef HAVE_SYSCONF
6115static struct constdef posix_constants_sysconf[] = {
6116#ifdef _SC_2_CHAR_TERM
6117 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6118#endif
6119#ifdef _SC_2_C_BIND
6120 {"SC_2_C_BIND", _SC_2_C_BIND},
6121#endif
6122#ifdef _SC_2_C_DEV
6123 {"SC_2_C_DEV", _SC_2_C_DEV},
6124#endif
6125#ifdef _SC_2_C_VERSION
6126 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6127#endif
6128#ifdef _SC_2_FORT_DEV
6129 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6130#endif
6131#ifdef _SC_2_FORT_RUN
6132 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6133#endif
6134#ifdef _SC_2_LOCALEDEF
6135 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6136#endif
6137#ifdef _SC_2_SW_DEV
6138 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6139#endif
6140#ifdef _SC_2_UPE
6141 {"SC_2_UPE", _SC_2_UPE},
6142#endif
6143#ifdef _SC_2_VERSION
6144 {"SC_2_VERSION", _SC_2_VERSION},
6145#endif
Fred Draked86ed291999-12-15 15:34:33 +00006146#ifdef _SC_ABI_ASYNCHRONOUS_IO
6147 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6148#endif
6149#ifdef _SC_ACL
6150 {"SC_ACL", _SC_ACL},
6151#endif
Fred Drakec9680921999-12-13 16:37:25 +00006152#ifdef _SC_AIO_LISTIO_MAX
6153 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6154#endif
Fred Drakec9680921999-12-13 16:37:25 +00006155#ifdef _SC_AIO_MAX
6156 {"SC_AIO_MAX", _SC_AIO_MAX},
6157#endif
6158#ifdef _SC_AIO_PRIO_DELTA_MAX
6159 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6160#endif
6161#ifdef _SC_ARG_MAX
6162 {"SC_ARG_MAX", _SC_ARG_MAX},
6163#endif
6164#ifdef _SC_ASYNCHRONOUS_IO
6165 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6166#endif
6167#ifdef _SC_ATEXIT_MAX
6168 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6169#endif
Fred Draked86ed291999-12-15 15:34:33 +00006170#ifdef _SC_AUDIT
6171 {"SC_AUDIT", _SC_AUDIT},
6172#endif
Fred Drakec9680921999-12-13 16:37:25 +00006173#ifdef _SC_AVPHYS_PAGES
6174 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6175#endif
6176#ifdef _SC_BC_BASE_MAX
6177 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6178#endif
6179#ifdef _SC_BC_DIM_MAX
6180 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6181#endif
6182#ifdef _SC_BC_SCALE_MAX
6183 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6184#endif
6185#ifdef _SC_BC_STRING_MAX
6186 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6187#endif
Fred Draked86ed291999-12-15 15:34:33 +00006188#ifdef _SC_CAP
6189 {"SC_CAP", _SC_CAP},
6190#endif
Fred Drakec9680921999-12-13 16:37:25 +00006191#ifdef _SC_CHARCLASS_NAME_MAX
6192 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6193#endif
6194#ifdef _SC_CHAR_BIT
6195 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6196#endif
6197#ifdef _SC_CHAR_MAX
6198 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6199#endif
6200#ifdef _SC_CHAR_MIN
6201 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6202#endif
6203#ifdef _SC_CHILD_MAX
6204 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6205#endif
6206#ifdef _SC_CLK_TCK
6207 {"SC_CLK_TCK", _SC_CLK_TCK},
6208#endif
6209#ifdef _SC_COHER_BLKSZ
6210 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6211#endif
6212#ifdef _SC_COLL_WEIGHTS_MAX
6213 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6214#endif
6215#ifdef _SC_DCACHE_ASSOC
6216 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6217#endif
6218#ifdef _SC_DCACHE_BLKSZ
6219 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6220#endif
6221#ifdef _SC_DCACHE_LINESZ
6222 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6223#endif
6224#ifdef _SC_DCACHE_SZ
6225 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6226#endif
6227#ifdef _SC_DCACHE_TBLKSZ
6228 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6229#endif
6230#ifdef _SC_DELAYTIMER_MAX
6231 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6232#endif
6233#ifdef _SC_EQUIV_CLASS_MAX
6234 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6235#endif
6236#ifdef _SC_EXPR_NEST_MAX
6237 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6238#endif
6239#ifdef _SC_FSYNC
6240 {"SC_FSYNC", _SC_FSYNC},
6241#endif
6242#ifdef _SC_GETGR_R_SIZE_MAX
6243 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6244#endif
6245#ifdef _SC_GETPW_R_SIZE_MAX
6246 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6247#endif
6248#ifdef _SC_ICACHE_ASSOC
6249 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6250#endif
6251#ifdef _SC_ICACHE_BLKSZ
6252 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6253#endif
6254#ifdef _SC_ICACHE_LINESZ
6255 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6256#endif
6257#ifdef _SC_ICACHE_SZ
6258 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6259#endif
Fred Draked86ed291999-12-15 15:34:33 +00006260#ifdef _SC_INF
6261 {"SC_INF", _SC_INF},
6262#endif
Fred Drakec9680921999-12-13 16:37:25 +00006263#ifdef _SC_INT_MAX
6264 {"SC_INT_MAX", _SC_INT_MAX},
6265#endif
6266#ifdef _SC_INT_MIN
6267 {"SC_INT_MIN", _SC_INT_MIN},
6268#endif
6269#ifdef _SC_IOV_MAX
6270 {"SC_IOV_MAX", _SC_IOV_MAX},
6271#endif
Fred Draked86ed291999-12-15 15:34:33 +00006272#ifdef _SC_IP_SECOPTS
6273 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6274#endif
Fred Drakec9680921999-12-13 16:37:25 +00006275#ifdef _SC_JOB_CONTROL
6276 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6277#endif
Fred Draked86ed291999-12-15 15:34:33 +00006278#ifdef _SC_KERN_POINTERS
6279 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6280#endif
6281#ifdef _SC_KERN_SIM
6282 {"SC_KERN_SIM", _SC_KERN_SIM},
6283#endif
Fred Drakec9680921999-12-13 16:37:25 +00006284#ifdef _SC_LINE_MAX
6285 {"SC_LINE_MAX", _SC_LINE_MAX},
6286#endif
6287#ifdef _SC_LOGIN_NAME_MAX
6288 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6289#endif
6290#ifdef _SC_LOGNAME_MAX
6291 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6292#endif
6293#ifdef _SC_LONG_BIT
6294 {"SC_LONG_BIT", _SC_LONG_BIT},
6295#endif
Fred Draked86ed291999-12-15 15:34:33 +00006296#ifdef _SC_MAC
6297 {"SC_MAC", _SC_MAC},
6298#endif
Fred Drakec9680921999-12-13 16:37:25 +00006299#ifdef _SC_MAPPED_FILES
6300 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6301#endif
6302#ifdef _SC_MAXPID
6303 {"SC_MAXPID", _SC_MAXPID},
6304#endif
6305#ifdef _SC_MB_LEN_MAX
6306 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6307#endif
6308#ifdef _SC_MEMLOCK
6309 {"SC_MEMLOCK", _SC_MEMLOCK},
6310#endif
6311#ifdef _SC_MEMLOCK_RANGE
6312 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6313#endif
6314#ifdef _SC_MEMORY_PROTECTION
6315 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6316#endif
6317#ifdef _SC_MESSAGE_PASSING
6318 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6319#endif
Fred Draked86ed291999-12-15 15:34:33 +00006320#ifdef _SC_MMAP_FIXED_ALIGNMENT
6321 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6322#endif
Fred Drakec9680921999-12-13 16:37:25 +00006323#ifdef _SC_MQ_OPEN_MAX
6324 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6325#endif
6326#ifdef _SC_MQ_PRIO_MAX
6327 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6328#endif
Fred Draked86ed291999-12-15 15:34:33 +00006329#ifdef _SC_NACLS_MAX
6330 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6331#endif
Fred Drakec9680921999-12-13 16:37:25 +00006332#ifdef _SC_NGROUPS_MAX
6333 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6334#endif
6335#ifdef _SC_NL_ARGMAX
6336 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6337#endif
6338#ifdef _SC_NL_LANGMAX
6339 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6340#endif
6341#ifdef _SC_NL_MSGMAX
6342 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6343#endif
6344#ifdef _SC_NL_NMAX
6345 {"SC_NL_NMAX", _SC_NL_NMAX},
6346#endif
6347#ifdef _SC_NL_SETMAX
6348 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6349#endif
6350#ifdef _SC_NL_TEXTMAX
6351 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6352#endif
6353#ifdef _SC_NPROCESSORS_CONF
6354 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6355#endif
6356#ifdef _SC_NPROCESSORS_ONLN
6357 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6358#endif
Fred Draked86ed291999-12-15 15:34:33 +00006359#ifdef _SC_NPROC_CONF
6360 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6361#endif
6362#ifdef _SC_NPROC_ONLN
6363 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6364#endif
Fred Drakec9680921999-12-13 16:37:25 +00006365#ifdef _SC_NZERO
6366 {"SC_NZERO", _SC_NZERO},
6367#endif
6368#ifdef _SC_OPEN_MAX
6369 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6370#endif
6371#ifdef _SC_PAGESIZE
6372 {"SC_PAGESIZE", _SC_PAGESIZE},
6373#endif
6374#ifdef _SC_PAGE_SIZE
6375 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6376#endif
6377#ifdef _SC_PASS_MAX
6378 {"SC_PASS_MAX", _SC_PASS_MAX},
6379#endif
6380#ifdef _SC_PHYS_PAGES
6381 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6382#endif
6383#ifdef _SC_PII
6384 {"SC_PII", _SC_PII},
6385#endif
6386#ifdef _SC_PII_INTERNET
6387 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6388#endif
6389#ifdef _SC_PII_INTERNET_DGRAM
6390 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6391#endif
6392#ifdef _SC_PII_INTERNET_STREAM
6393 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6394#endif
6395#ifdef _SC_PII_OSI
6396 {"SC_PII_OSI", _SC_PII_OSI},
6397#endif
6398#ifdef _SC_PII_OSI_CLTS
6399 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6400#endif
6401#ifdef _SC_PII_OSI_COTS
6402 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6403#endif
6404#ifdef _SC_PII_OSI_M
6405 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6406#endif
6407#ifdef _SC_PII_SOCKET
6408 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6409#endif
6410#ifdef _SC_PII_XTI
6411 {"SC_PII_XTI", _SC_PII_XTI},
6412#endif
6413#ifdef _SC_POLL
6414 {"SC_POLL", _SC_POLL},
6415#endif
6416#ifdef _SC_PRIORITIZED_IO
6417 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6418#endif
6419#ifdef _SC_PRIORITY_SCHEDULING
6420 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6421#endif
6422#ifdef _SC_REALTIME_SIGNALS
6423 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6424#endif
6425#ifdef _SC_RE_DUP_MAX
6426 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6427#endif
6428#ifdef _SC_RTSIG_MAX
6429 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6430#endif
6431#ifdef _SC_SAVED_IDS
6432 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6433#endif
6434#ifdef _SC_SCHAR_MAX
6435 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6436#endif
6437#ifdef _SC_SCHAR_MIN
6438 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6439#endif
6440#ifdef _SC_SELECT
6441 {"SC_SELECT", _SC_SELECT},
6442#endif
6443#ifdef _SC_SEMAPHORES
6444 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6445#endif
6446#ifdef _SC_SEM_NSEMS_MAX
6447 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6448#endif
6449#ifdef _SC_SEM_VALUE_MAX
6450 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6451#endif
6452#ifdef _SC_SHARED_MEMORY_OBJECTS
6453 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6454#endif
6455#ifdef _SC_SHRT_MAX
6456 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6457#endif
6458#ifdef _SC_SHRT_MIN
6459 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6460#endif
6461#ifdef _SC_SIGQUEUE_MAX
6462 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6463#endif
6464#ifdef _SC_SIGRT_MAX
6465 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6466#endif
6467#ifdef _SC_SIGRT_MIN
6468 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6469#endif
Fred Draked86ed291999-12-15 15:34:33 +00006470#ifdef _SC_SOFTPOWER
6471 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6472#endif
Fred Drakec9680921999-12-13 16:37:25 +00006473#ifdef _SC_SPLIT_CACHE
6474 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6475#endif
6476#ifdef _SC_SSIZE_MAX
6477 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6478#endif
6479#ifdef _SC_STACK_PROT
6480 {"SC_STACK_PROT", _SC_STACK_PROT},
6481#endif
6482#ifdef _SC_STREAM_MAX
6483 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6484#endif
6485#ifdef _SC_SYNCHRONIZED_IO
6486 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6487#endif
6488#ifdef _SC_THREADS
6489 {"SC_THREADS", _SC_THREADS},
6490#endif
6491#ifdef _SC_THREAD_ATTR_STACKADDR
6492 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6493#endif
6494#ifdef _SC_THREAD_ATTR_STACKSIZE
6495 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6496#endif
6497#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6498 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6499#endif
6500#ifdef _SC_THREAD_KEYS_MAX
6501 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6502#endif
6503#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6504 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6505#endif
6506#ifdef _SC_THREAD_PRIO_INHERIT
6507 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6508#endif
6509#ifdef _SC_THREAD_PRIO_PROTECT
6510 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6511#endif
6512#ifdef _SC_THREAD_PROCESS_SHARED
6513 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6514#endif
6515#ifdef _SC_THREAD_SAFE_FUNCTIONS
6516 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6517#endif
6518#ifdef _SC_THREAD_STACK_MIN
6519 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6520#endif
6521#ifdef _SC_THREAD_THREADS_MAX
6522 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6523#endif
6524#ifdef _SC_TIMERS
6525 {"SC_TIMERS", _SC_TIMERS},
6526#endif
6527#ifdef _SC_TIMER_MAX
6528 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6529#endif
6530#ifdef _SC_TTY_NAME_MAX
6531 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6532#endif
6533#ifdef _SC_TZNAME_MAX
6534 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6535#endif
6536#ifdef _SC_T_IOV_MAX
6537 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6538#endif
6539#ifdef _SC_UCHAR_MAX
6540 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6541#endif
6542#ifdef _SC_UINT_MAX
6543 {"SC_UINT_MAX", _SC_UINT_MAX},
6544#endif
6545#ifdef _SC_UIO_MAXIOV
6546 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6547#endif
6548#ifdef _SC_ULONG_MAX
6549 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6550#endif
6551#ifdef _SC_USHRT_MAX
6552 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6553#endif
6554#ifdef _SC_VERSION
6555 {"SC_VERSION", _SC_VERSION},
6556#endif
6557#ifdef _SC_WORD_BIT
6558 {"SC_WORD_BIT", _SC_WORD_BIT},
6559#endif
6560#ifdef _SC_XBS5_ILP32_OFF32
6561 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6562#endif
6563#ifdef _SC_XBS5_ILP32_OFFBIG
6564 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6565#endif
6566#ifdef _SC_XBS5_LP64_OFF64
6567 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6568#endif
6569#ifdef _SC_XBS5_LPBIG_OFFBIG
6570 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6571#endif
6572#ifdef _SC_XOPEN_CRYPT
6573 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6574#endif
6575#ifdef _SC_XOPEN_ENH_I18N
6576 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6577#endif
6578#ifdef _SC_XOPEN_LEGACY
6579 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6580#endif
6581#ifdef _SC_XOPEN_REALTIME
6582 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6583#endif
6584#ifdef _SC_XOPEN_REALTIME_THREADS
6585 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6586#endif
6587#ifdef _SC_XOPEN_SHM
6588 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6589#endif
6590#ifdef _SC_XOPEN_UNIX
6591 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6592#endif
6593#ifdef _SC_XOPEN_VERSION
6594 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6595#endif
6596#ifdef _SC_XOPEN_XCU_VERSION
6597 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6598#endif
6599#ifdef _SC_XOPEN_XPG2
6600 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6601#endif
6602#ifdef _SC_XOPEN_XPG3
6603 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6604#endif
6605#ifdef _SC_XOPEN_XPG4
6606 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6607#endif
6608};
6609
6610static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006611conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006612{
6613 return conv_confname(arg, valuep, posix_constants_sysconf,
6614 sizeof(posix_constants_sysconf)
6615 / sizeof(struct constdef));
6616}
6617
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006618PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006619"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006620Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006621
6622static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006623posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006624{
6625 PyObject *result = NULL;
6626 int name;
6627
6628 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6629 int value;
6630
6631 errno = 0;
6632 value = sysconf(name);
6633 if (value == -1 && errno != 0)
6634 posix_error();
6635 else
6636 result = PyInt_FromLong(value);
6637 }
6638 return result;
6639}
6640#endif
6641
6642
Fred Drakebec628d1999-12-15 18:31:10 +00006643/* This code is used to ensure that the tables of configuration value names
6644 * are in sorted order as required by conv_confname(), and also to build the
6645 * the exported dictionaries that are used to publish information about the
6646 * names available on the host platform.
6647 *
6648 * Sorting the table at runtime ensures that the table is properly ordered
6649 * when used, even for platforms we're not able to test on. It also makes
6650 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006651 */
Fred Drakebec628d1999-12-15 18:31:10 +00006652
6653static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006654cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006655{
6656 const struct constdef *c1 =
6657 (const struct constdef *) v1;
6658 const struct constdef *c2 =
6659 (const struct constdef *) v2;
6660
6661 return strcmp(c1->name, c2->name);
6662}
6663
6664static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006665setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006666 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006667{
Fred Drakebec628d1999-12-15 18:31:10 +00006668 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006669 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006670
6671 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6672 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006673 if (d == NULL)
6674 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006675
Barry Warsaw3155db32000-04-13 15:20:40 +00006676 for (i=0; i < tablesize; ++i) {
6677 PyObject *o = PyInt_FromLong(table[i].value);
6678 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6679 Py_XDECREF(o);
6680 Py_DECREF(d);
6681 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006682 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006683 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006684 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006685 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006686}
6687
Fred Drakebec628d1999-12-15 18:31:10 +00006688/* Return -1 on failure, 0 on success. */
6689static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006690setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006691{
6692#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006693 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006694 sizeof(posix_constants_pathconf)
6695 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006696 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006697 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006698#endif
6699#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006700 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006701 sizeof(posix_constants_confstr)
6702 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006703 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006704 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006705#endif
6706#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006707 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006708 sizeof(posix_constants_sysconf)
6709 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006710 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006711 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006712#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006713 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006714}
Fred Draked86ed291999-12-15 15:34:33 +00006715
6716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006717PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006718"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006719Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006720in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006721
6722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006723posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006724{
6725 if (!PyArg_ParseTuple(args, ":abort"))
6726 return NULL;
6727 abort();
6728 /*NOTREACHED*/
6729 Py_FatalError("abort() called from Python code didn't abort!");
6730 return NULL;
6731}
Fred Drakebec628d1999-12-15 18:31:10 +00006732
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006733#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006734PyDoc_STRVAR(win32_startfile__doc__,
6735"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006736\n\
6737This acts like double-clicking the file in Explorer, or giving the file\n\
6738name as an argument to the DOS \"start\" command: the file is opened\n\
6739with whatever application (if any) its extension is associated.\n\
6740\n\
6741startfile returns as soon as the associated application is launched.\n\
6742There is no option to wait for the application to close, and no way\n\
6743to retrieve the application's exit status.\n\
6744\n\
6745The filepath is relative to the current directory. If you want to use\n\
6746an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006747the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006748
6749static PyObject *
6750win32_startfile(PyObject *self, PyObject *args)
6751{
6752 char *filepath;
6753 HINSTANCE rc;
6754 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6755 return NULL;
6756 Py_BEGIN_ALLOW_THREADS
6757 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6758 Py_END_ALLOW_THREADS
6759 if (rc <= (HINSTANCE)32)
6760 return win32_error("startfile", filepath);
6761 Py_INCREF(Py_None);
6762 return Py_None;
6763}
6764#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006765
6766static PyMethodDef posix_methods[] = {
6767 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6768#ifdef HAVE_TTYNAME
6769 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6770#endif
6771 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6772 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006773#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006774 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006775#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006776#ifdef HAVE_LCHOWN
6777 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6778#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006779#ifdef HAVE_CHROOT
6780 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6781#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006782#ifdef HAVE_CTERMID
6783 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6784#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006785#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006786 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006787 {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006788#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006789#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006790 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006791#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006792 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6793 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6794 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006795#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006796 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006797#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006798#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006799 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006800#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006801 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6802 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6803 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006804#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006805 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006806#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006807#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006808 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006809#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006810 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006811#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006812 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006813#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006814 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6815 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6816 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006817#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006818 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006819#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006820 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006821#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006822 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6823 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006824#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006825#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006826 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6827 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006828#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006829#ifdef HAVE_FORK1
6830 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6831#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006832#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006833 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006834#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006835#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006836 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006837#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006838#ifdef HAVE_FORKPTY
6839 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6840#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006841#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006842 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006843#endif /* HAVE_GETEGID */
6844#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006845 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006846#endif /* HAVE_GETEUID */
6847#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006848 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006849#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006850#ifdef HAVE_GETGROUPS
6851 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6852#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006853 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006854#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006855 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006856#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006857#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006858 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006859#endif /* HAVE_GETPPID */
6860#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006861 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006862#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006863#ifdef HAVE_GETLOGIN
6864 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6865#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006866#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006867 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006868#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006869#ifdef HAVE_KILLPG
6870 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6871#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006872#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006873 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006874#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006875#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006876 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006877#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006878 {"popen2", win32_popen2, METH_VARARGS},
6879 {"popen3", win32_popen3, METH_VARARGS},
6880 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006881 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006882#else
6883#if defined(PYOS_OS2) && defined(PYCC_GCC)
6884 {"popen2", os2emx_popen2, METH_VARARGS},
6885 {"popen3", os2emx_popen3, METH_VARARGS},
6886 {"popen4", os2emx_popen4, METH_VARARGS},
6887#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006888#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006889#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006890#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006891 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006892#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006893#ifdef HAVE_SETEUID
6894 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6895#endif /* HAVE_SETEUID */
6896#ifdef HAVE_SETEGID
6897 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6898#endif /* HAVE_SETEGID */
6899#ifdef HAVE_SETREUID
6900 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6901#endif /* HAVE_SETREUID */
6902#ifdef HAVE_SETREGID
6903 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6904#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006905#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006906 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006907#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006908#ifdef HAVE_SETGROUPS
6909 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6910#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006911#ifdef HAVE_GETPGID
6912 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6913#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006914#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006915 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006916#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006917#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006918 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006919#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006920#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006921 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006922#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006923#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006924 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006925#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006926#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006927 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006928#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006929#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006930 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006931#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006932#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006933 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006934#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006935 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6936 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6937 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6938 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6939 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6940 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6941 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6942 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6943 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006944 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006945#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006946 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006947#endif
6948#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006949 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006950#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006951#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006952 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6953#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006954#ifdef HAVE_DEVICE_MACROS
6955 {"major", posix_major, METH_VARARGS, posix_major__doc__},
6956 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
6957 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
6958#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006959#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006960 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006961#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006962#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006963 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006964#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006965#ifdef HAVE_UNSETENV
6966 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6967#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006968#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006969 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006970#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006971#ifdef HAVE_FCHDIR
6972 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6973#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006974#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006975 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006976#endif
6977#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006978 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006979#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006980#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006981#ifdef WCOREDUMP
6982 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6983#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006984#ifdef WIFCONTINUED
6985 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6986#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006987#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006988 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006989#endif /* WIFSTOPPED */
6990#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006991 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006992#endif /* WIFSIGNALED */
6993#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006994 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006995#endif /* WIFEXITED */
6996#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006997 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006998#endif /* WEXITSTATUS */
6999#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007000 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007001#endif /* WTERMSIG */
7002#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007003 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007004#endif /* WSTOPSIG */
7005#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007006#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007007 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007008#endif
7009#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007010 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007011#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007012#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007013 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
7014#endif
7015#ifdef HAVE_TEMPNAM
7016 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7017#endif
7018#ifdef HAVE_TMPNAM
7019 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
7020#endif
Fred Drakec9680921999-12-13 16:37:25 +00007021#ifdef HAVE_CONFSTR
7022 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7023#endif
7024#ifdef HAVE_SYSCONF
7025 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7026#endif
7027#ifdef HAVE_FPATHCONF
7028 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7029#endif
7030#ifdef HAVE_PATHCONF
7031 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7032#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007033 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007034#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007035 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7036#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007037 {NULL, NULL} /* Sentinel */
7038};
7039
7040
Barry Warsaw4a342091996-12-19 23:50:02 +00007041static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007042ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007043{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007044 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007045}
7046
Guido van Rossumd48f2521997-12-05 22:19:34 +00007047#if defined(PYOS_OS2)
7048/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007049static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007050{
7051 APIRET rc;
7052 ULONG values[QSV_MAX+1];
7053 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007054 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007055
7056 Py_BEGIN_ALLOW_THREADS
7057 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7058 Py_END_ALLOW_THREADS
7059
7060 if (rc != NO_ERROR) {
7061 os2_error(rc);
7062 return -1;
7063 }
7064
Fred Drake4d1e64b2002-04-15 19:40:07 +00007065 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7066 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7067 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7068 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7069 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7070 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7071 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007072
7073 switch (values[QSV_VERSION_MINOR]) {
7074 case 0: ver = "2.00"; break;
7075 case 10: ver = "2.10"; break;
7076 case 11: ver = "2.11"; break;
7077 case 30: ver = "3.00"; break;
7078 case 40: ver = "4.00"; break;
7079 case 50: ver = "5.00"; break;
7080 default:
Tim Peters885d4572001-11-28 20:27:42 +00007081 PyOS_snprintf(tmp, sizeof(tmp),
7082 "%d-%d", values[QSV_VERSION_MAJOR],
7083 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007084 ver = &tmp[0];
7085 }
7086
7087 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007088 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007089 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007090
7091 /* Add Indicator of Which Drive was Used to Boot the System */
7092 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7093 tmp[1] = ':';
7094 tmp[2] = '\0';
7095
Fred Drake4d1e64b2002-04-15 19:40:07 +00007096 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007097}
7098#endif
7099
Barry Warsaw4a342091996-12-19 23:50:02 +00007100static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007101all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007102{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007103#ifdef F_OK
7104 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007105#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007106#ifdef R_OK
7107 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007108#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007109#ifdef W_OK
7110 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007111#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007112#ifdef X_OK
7113 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007114#endif
Fred Drakec9680921999-12-13 16:37:25 +00007115#ifdef NGROUPS_MAX
7116 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7117#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007118#ifdef TMP_MAX
7119 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7120#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007121#ifdef WCONTINUED
7122 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7123#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007124#ifdef WNOHANG
7125 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007126#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007127#ifdef WUNTRACED
7128 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7129#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007130#ifdef O_RDONLY
7131 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7132#endif
7133#ifdef O_WRONLY
7134 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7135#endif
7136#ifdef O_RDWR
7137 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7138#endif
7139#ifdef O_NDELAY
7140 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7141#endif
7142#ifdef O_NONBLOCK
7143 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7144#endif
7145#ifdef O_APPEND
7146 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7147#endif
7148#ifdef O_DSYNC
7149 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7150#endif
7151#ifdef O_RSYNC
7152 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7153#endif
7154#ifdef O_SYNC
7155 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7156#endif
7157#ifdef O_NOCTTY
7158 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7159#endif
7160#ifdef O_CREAT
7161 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7162#endif
7163#ifdef O_EXCL
7164 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7165#endif
7166#ifdef O_TRUNC
7167 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7168#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007169#ifdef O_BINARY
7170 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7171#endif
7172#ifdef O_TEXT
7173 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7174#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007175#ifdef O_LARGEFILE
7176 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7177#endif
7178
Tim Peters5aa91602002-01-30 05:46:57 +00007179/* MS Windows */
7180#ifdef O_NOINHERIT
7181 /* Don't inherit in child processes. */
7182 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7183#endif
7184#ifdef _O_SHORT_LIVED
7185 /* Optimize for short life (keep in memory). */
7186 /* MS forgot to define this one with a non-underscore form too. */
7187 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7188#endif
7189#ifdef O_TEMPORARY
7190 /* Automatically delete when last handle is closed. */
7191 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7192#endif
7193#ifdef O_RANDOM
7194 /* Optimize for random access. */
7195 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7196#endif
7197#ifdef O_SEQUENTIAL
7198 /* Optimize for sequential access. */
7199 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7200#endif
7201
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007202/* GNU extensions. */
7203#ifdef O_DIRECT
7204 /* Direct disk access. */
7205 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7206#endif
7207#ifdef O_DIRECTORY
7208 /* Must be a directory. */
7209 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7210#endif
7211#ifdef O_NOFOLLOW
7212 /* Do not follow links. */
7213 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7214#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007215
Guido van Rossum246bc171999-02-01 23:54:31 +00007216#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007217#if defined(PYOS_OS2) && defined(PYCC_GCC)
7218 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7219 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7220 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7221 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7222 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7223 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7224 if (ins(d, "P_PM", (long)P_PM)) return -1;
7225 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7226 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7227 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7228 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7229 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7230 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7231 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7232 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7233 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7234 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7235 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7236 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7237 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7238#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007239 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7240 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7241 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7242 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7243 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007244#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007245#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007246
Guido van Rossumd48f2521997-12-05 22:19:34 +00007247#if defined(PYOS_OS2)
7248 if (insertvalues(d)) return -1;
7249#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007250 return 0;
7251}
7252
7253
Tim Peters5aa91602002-01-30 05:46:57 +00007254#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007255#define INITFUNC initnt
7256#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007257
7258#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007259#define INITFUNC initos2
7260#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007261
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007262#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007263#define INITFUNC initposix
7264#define MODNAME "posix"
7265#endif
7266
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007267PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007268INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007269{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007270 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007271
Fred Drake4d1e64b2002-04-15 19:40:07 +00007272 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007273 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007274 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007275
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007276 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007277 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007278 Py_XINCREF(v);
7279 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007280 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007281 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007282
Fred Drake4d1e64b2002-04-15 19:40:07 +00007283 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007284 return;
7285
Fred Drake4d1e64b2002-04-15 19:40:07 +00007286 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007287 return;
7288
Fred Drake4d1e64b2002-04-15 19:40:07 +00007289 Py_INCREF(PyExc_OSError);
7290 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007291
Guido van Rossumb3d39562000-01-31 18:41:26 +00007292#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007293 if (posix_putenv_garbage == NULL)
7294 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007295#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007296
Guido van Rossum14648392001-12-08 18:02:58 +00007297 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007298 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007299 Py_INCREF((PyObject*) &StatResultType);
7300 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007301
Guido van Rossum14648392001-12-08 18:02:58 +00007302 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007303 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007304 Py_INCREF((PyObject*) &StatVFSResultType);
7305 PyModule_AddObject(m, "statvfs_result",
7306 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007307}