blob: 0f2fbb9752f10ca1a920f64350aa3494fa0ee07c [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",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002010 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002011 &argvlist[i]))
2012 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002013 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002014 goto fail_1;
2015 }
2016 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002017 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002018 argvlist[argc] = NULL;
2019
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002020 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00002021 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002022 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002023 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002024 goto fail_1;
2025 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002026 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002027 keys = PyMapping_Keys(env);
2028 vals = PyMapping_Values(env);
2029 if (!keys || !vals)
2030 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002031
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002032 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002033 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002034 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002035
2036 key = PyList_GetItem(keys, pos);
2037 val = PyList_GetItem(vals, pos);
2038 if (!key || !val)
2039 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002040
Fred Drake661ea262000-10-24 19:57:45 +00002041 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
2042 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002043 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002044 goto fail_2;
2045 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002046
2047#if defined(PYOS_OS2)
2048 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2049 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2050#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002051 len = PyString_Size(key) + PyString_Size(val) + 2;
2052 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002053 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002054 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002055 goto fail_2;
2056 }
Tim Petersc8996f52001-12-03 20:41:00 +00002057 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002058 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002059#if defined(PYOS_OS2)
2060 }
2061#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002062 }
2063 envlist[envc] = 0;
2064
Guido van Rossumb6775db1994-08-01 11:34:53 +00002065
2066#ifdef BAD_EXEC_PROTOTYPES
2067 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002068#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002069 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002070#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002071
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002072 /* If we get here it's definitely an error */
2073
2074 (void) posix_error();
2075
2076 fail_2:
2077 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002078 PyMem_DEL(envlist[envc]);
2079 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002080 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002081 free_string_array(argvlist,lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002082 Py_XDECREF(vals);
2083 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002084 fail_0:
2085 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002086 return NULL;
2087}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002088#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002090
Guido van Rossuma1065681999-01-25 23:20:23 +00002091#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002092PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002093"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002094Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002095\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002096 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002097 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002098 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002099
2100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002101posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002102{
2103 char *path;
2104 PyObject *argv;
2105 char **argvlist;
2106 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002107 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002108 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002109
2110 /* spawnv has three arguments: (mode, path, argv), where
2111 argv is a list or tuple of strings. */
2112
Martin v. Löwis114619e2002-10-07 06:44:21 +00002113 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2114 Py_FileSystemDefaultEncoding,
2115 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002116 return NULL;
2117 if (PyList_Check(argv)) {
2118 argc = PyList_Size(argv);
2119 getitem = PyList_GetItem;
2120 }
2121 else if (PyTuple_Check(argv)) {
2122 argc = PyTuple_Size(argv);
2123 getitem = PyTuple_GetItem;
2124 }
2125 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00002126 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002127 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002128 return NULL;
2129 }
2130
2131 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002132 if (argvlist == NULL) {
2133 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002134 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002135 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002136 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002137 if (!PyArg_Parse((*getitem)(argv, i), "et",
2138 Py_FileSystemDefaultEncoding,
2139 &argvlist[i])) {
2140 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002141 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002142 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002143 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002144 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002145 }
2146 }
2147 argvlist[argc] = NULL;
2148
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002149#if defined(PYOS_OS2) && defined(PYCC_GCC)
2150 Py_BEGIN_ALLOW_THREADS
2151 spawnval = spawnv(mode, path, argvlist);
2152 Py_END_ALLOW_THREADS
2153#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002154 if (mode == _OLD_P_OVERLAY)
2155 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002156
Tim Peters25059d32001-12-07 20:35:43 +00002157 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002158 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002159 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002160#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002161
Martin v. Löwis114619e2002-10-07 06:44:21 +00002162 free_string_array(argvlist, argc);
2163 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002164
Fred Drake699f3522000-06-29 21:12:41 +00002165 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002166 return posix_error();
2167 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002168#if SIZEOF_LONG == SIZEOF_VOID_P
2169 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002170#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002171 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002172#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002173}
2174
2175
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002176PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002177"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002178Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002179\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002180 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002181 path: path of executable file\n\
2182 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002183 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002184
2185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002186posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002187{
2188 char *path;
2189 PyObject *argv, *env;
2190 char **argvlist;
2191 char **envlist;
2192 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2193 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002194 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002195 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002196 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002197
2198 /* spawnve has four arguments: (mode, path, argv, env), where
2199 argv is a list or tuple of strings and env is a dictionary
2200 like posix.environ. */
2201
Martin v. Löwis114619e2002-10-07 06:44:21 +00002202 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2203 Py_FileSystemDefaultEncoding,
2204 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002205 return NULL;
2206 if (PyList_Check(argv)) {
2207 argc = PyList_Size(argv);
2208 getitem = PyList_GetItem;
2209 }
2210 else if (PyTuple_Check(argv)) {
2211 argc = PyTuple_Size(argv);
2212 getitem = PyTuple_GetItem;
2213 }
2214 else {
Fred Drake661ea262000-10-24 19:57:45 +00002215 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002216 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002217 }
2218 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00002219 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002220 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002221 }
2222
2223 argvlist = PyMem_NEW(char *, argc+1);
2224 if (argvlist == NULL) {
2225 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002226 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002227 }
2228 for (i = 0; i < argc; i++) {
2229 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002230 "et;spawnve() arg 2 must contain only strings",
2231 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002232 &argvlist[i]))
2233 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002234 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002235 goto fail_1;
2236 }
2237 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002238 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002239 argvlist[argc] = NULL;
2240
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002241 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00002242 envlist = PyMem_NEW(char *, i + 1);
2243 if (envlist == NULL) {
2244 PyErr_NoMemory();
2245 goto fail_1;
2246 }
2247 envc = 0;
2248 keys = PyMapping_Keys(env);
2249 vals = PyMapping_Values(env);
2250 if (!keys || !vals)
2251 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002252
Guido van Rossuma1065681999-01-25 23:20:23 +00002253 for (pos = 0; pos < i; pos++) {
2254 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002255 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002256
2257 key = PyList_GetItem(keys, pos);
2258 val = PyList_GetItem(vals, pos);
2259 if (!key || !val)
2260 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002261
Fred Drake661ea262000-10-24 19:57:45 +00002262 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
2263 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002264 {
2265 goto fail_2;
2266 }
Tim Petersc8996f52001-12-03 20:41:00 +00002267 len = PyString_Size(key) + PyString_Size(val) + 2;
2268 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002269 if (p == NULL) {
2270 PyErr_NoMemory();
2271 goto fail_2;
2272 }
Tim Petersc8996f52001-12-03 20:41:00 +00002273 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002274 envlist[envc++] = p;
2275 }
2276 envlist[envc] = 0;
2277
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002278#if defined(PYOS_OS2) && defined(PYCC_GCC)
2279 Py_BEGIN_ALLOW_THREADS
2280 spawnval = spawnve(mode, path, argvlist, envlist);
2281 Py_END_ALLOW_THREADS
2282#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002283 if (mode == _OLD_P_OVERLAY)
2284 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002285
2286 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002287 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002288 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002289#endif
Tim Peters25059d32001-12-07 20:35:43 +00002290
Fred Drake699f3522000-06-29 21:12:41 +00002291 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002292 (void) posix_error();
2293 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002294#if SIZEOF_LONG == SIZEOF_VOID_P
2295 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002296#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002297 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002298#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002299
2300 fail_2:
2301 while (--envc >= 0)
2302 PyMem_DEL(envlist[envc]);
2303 PyMem_DEL(envlist);
2304 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002305 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002306 Py_XDECREF(vals);
2307 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002308 fail_0:
2309 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002310 return res;
2311}
2312#endif /* HAVE_SPAWNV */
2313
2314
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002315#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002316PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002317"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002318Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2319\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002320Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002321
2322static PyObject *
2323posix_fork1(self, args)
2324 PyObject *self;
2325 PyObject *args;
2326{
2327 int pid;
2328 if (!PyArg_ParseTuple(args, ":fork1"))
2329 return NULL;
2330 pid = fork1();
2331 if (pid == -1)
2332 return posix_error();
2333 PyOS_AfterFork();
2334 return PyInt_FromLong((long)pid);
2335}
2336#endif
2337
2338
Guido van Rossumad0ee831995-03-01 10:34:45 +00002339#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002340PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002341"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002342Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002343Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002344
Barry Warsaw53699e91996-12-10 23:23:01 +00002345static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002346posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002347{
2348 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002349 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002350 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002351 pid = fork();
2352 if (pid == -1)
2353 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002354 if (pid == 0)
2355 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002356 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002357}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002358#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002359
Fred Drake8cef4cf2000-06-28 16:40:38 +00002360#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
2361#ifdef HAVE_PTY_H
2362#include <pty.h>
2363#else
2364#ifdef HAVE_LIBUTIL_H
2365#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002366#endif /* HAVE_LIBUTIL_H */
2367#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002368#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002369
Thomas Wouters70c21a12000-07-14 14:28:33 +00002370#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002371PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002372"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002373Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002374
2375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002376posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002377{
2378 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002379#ifndef HAVE_OPENPTY
2380 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002381#endif
2382
Fred Drake8cef4cf2000-06-28 16:40:38 +00002383 if (!PyArg_ParseTuple(args, ":openpty"))
2384 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002385
2386#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002387 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2388 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00002389#else
2390 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2391 if (slave_name == NULL)
2392 return posix_error();
2393
2394 slave_fd = open(slave_name, O_RDWR);
2395 if (slave_fd < 0)
2396 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002397#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002398
Fred Drake8cef4cf2000-06-28 16:40:38 +00002399 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002400
Fred Drake8cef4cf2000-06-28 16:40:38 +00002401}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002402#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002403
2404#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002405PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002406"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002407Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2408Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002409To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002410
2411static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002412posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002413{
2414 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002415
Fred Drake8cef4cf2000-06-28 16:40:38 +00002416 if (!PyArg_ParseTuple(args, ":forkpty"))
2417 return NULL;
2418 pid = forkpty(&master_fd, NULL, NULL, NULL);
2419 if (pid == -1)
2420 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002421 if (pid == 0)
2422 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002423 return Py_BuildValue("(ii)", pid, master_fd);
2424}
2425#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002426
Guido van Rossumad0ee831995-03-01 10:34:45 +00002427#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002428PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002429"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002430Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002431
Barry Warsaw53699e91996-12-10 23:23:01 +00002432static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002433posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002434{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002435 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002436 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002437 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002438}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002439#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002440
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002441
Guido van Rossumad0ee831995-03-01 10:34:45 +00002442#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002443PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002444"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002445Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002446
Barry Warsaw53699e91996-12-10 23:23:01 +00002447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002448posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002449{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002450 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002451 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002452 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002453}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002454#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002455
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002456
Guido van Rossumad0ee831995-03-01 10:34:45 +00002457#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002458PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002459"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002460Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002461
Barry Warsaw53699e91996-12-10 23:23:01 +00002462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002463posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002464{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002465 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002466 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002467 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002468}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002469#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002471
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002472PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002473"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002474Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002475
Barry Warsaw53699e91996-12-10 23:23:01 +00002476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002477posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002478{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002479 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002480 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002481 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002482}
2483
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002484
Fred Drakec9680921999-12-13 16:37:25 +00002485#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002486PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002487"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002488Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002489
2490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002491posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002492{
2493 PyObject *result = NULL;
2494
2495 if (PyArg_ParseTuple(args, ":getgroups")) {
2496#ifdef NGROUPS_MAX
2497#define MAX_GROUPS NGROUPS_MAX
2498#else
2499 /* defined to be 16 on Solaris7, so this should be a small number */
2500#define MAX_GROUPS 64
2501#endif
2502 gid_t grouplist[MAX_GROUPS];
2503 int n;
2504
2505 n = getgroups(MAX_GROUPS, grouplist);
2506 if (n < 0)
2507 posix_error();
2508 else {
2509 result = PyList_New(n);
2510 if (result != NULL) {
2511 PyObject *o;
2512 int i;
2513 for (i = 0; i < n; ++i) {
2514 o = PyInt_FromLong((long)grouplist[i]);
2515 if (o == NULL) {
2516 Py_DECREF(result);
2517 result = NULL;
2518 break;
2519 }
2520 PyList_SET_ITEM(result, i, o);
2521 }
2522 }
2523 }
2524 }
2525 return result;
2526}
2527#endif
2528
Martin v. Löwis606edc12002-06-13 21:09:11 +00002529#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002530PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002531"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002532Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002533
2534static PyObject *
2535posix_getpgid(PyObject *self, PyObject *args)
2536{
2537 int pid, pgid;
2538 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2539 return NULL;
2540 pgid = getpgid(pid);
2541 if (pgid < 0)
2542 return posix_error();
2543 return PyInt_FromLong((long)pgid);
2544}
2545#endif /* HAVE_GETPGID */
2546
2547
Guido van Rossumb6775db1994-08-01 11:34:53 +00002548#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002549PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002550"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002551Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002552
Barry Warsaw53699e91996-12-10 23:23:01 +00002553static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002554posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002555{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002556 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002557 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002558#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002559 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002560#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002561 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002562#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002563}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002564#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002566
Guido van Rossumb6775db1994-08-01 11:34:53 +00002567#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002568PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002569"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002570Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002571
Barry Warsaw53699e91996-12-10 23:23:01 +00002572static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002573posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002574{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002575 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002576 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002577#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002578 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002579#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002580 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002581#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002582 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002583 Py_INCREF(Py_None);
2584 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002585}
2586
Guido van Rossumb6775db1994-08-01 11:34:53 +00002587#endif /* HAVE_SETPGRP */
2588
Guido van Rossumad0ee831995-03-01 10:34:45 +00002589#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002590PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002591"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002592Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002593
Barry Warsaw53699e91996-12-10 23:23:01 +00002594static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002595posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002596{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002597 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002598 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002599 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002600}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002601#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002603
Fred Drake12c6e2d1999-12-14 21:25:03 +00002604#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002605PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002606"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002607Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002608
2609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002610posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002611{
2612 PyObject *result = NULL;
2613
2614 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002615 char *name;
2616 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002617
Fred Drakea30680b2000-12-06 21:24:28 +00002618 errno = 0;
2619 name = getlogin();
2620 if (name == NULL) {
2621 if (errno)
2622 posix_error();
2623 else
2624 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002625 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002626 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002627 else
2628 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002629 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002630 }
2631 return result;
2632}
2633#endif
2634
Guido van Rossumad0ee831995-03-01 10:34:45 +00002635#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002636PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002637"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002638Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002639
Barry Warsaw53699e91996-12-10 23:23:01 +00002640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002641posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002642{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002643 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002644 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002645 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002646}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002647#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002648
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002649
Guido van Rossumad0ee831995-03-01 10:34:45 +00002650#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002651PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002652"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002653Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002654
Barry Warsaw53699e91996-12-10 23:23:01 +00002655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002656posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002657{
2658 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002659 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002660 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002661#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002662 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2663 APIRET rc;
2664 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002665 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002666
2667 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2668 APIRET rc;
2669 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002670 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002671
2672 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002673 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002674#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002675 if (kill(pid, sig) == -1)
2676 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002677#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002678 Py_INCREF(Py_None);
2679 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002680}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002681#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002682
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002683#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002684PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002685"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002686Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002687
2688static PyObject *
2689posix_killpg(PyObject *self, PyObject *args)
2690{
2691 int pgid, sig;
2692 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2693 return NULL;
2694 if (killpg(pgid, sig) == -1)
2695 return posix_error();
2696 Py_INCREF(Py_None);
2697 return Py_None;
2698}
2699#endif
2700
Guido van Rossumc0125471996-06-28 18:55:32 +00002701#ifdef HAVE_PLOCK
2702
2703#ifdef HAVE_SYS_LOCK_H
2704#include <sys/lock.h>
2705#endif
2706
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002707PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002708"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002709Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002710
Barry Warsaw53699e91996-12-10 23:23:01 +00002711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002712posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002713{
2714 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002715 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002716 return NULL;
2717 if (plock(op) == -1)
2718 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002719 Py_INCREF(Py_None);
2720 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002721}
2722#endif
2723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002724
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002725#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002726PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002727"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002728Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002729
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002730#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002731#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002732static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002733async_system(const char *command)
2734{
2735 char *p, errormsg[256], args[1024];
2736 RESULTCODES rcodes;
2737 APIRET rc;
2738 char *shell = getenv("COMSPEC");
2739 if (!shell)
2740 shell = "cmd";
2741
2742 strcpy(args, shell);
2743 p = &args[ strlen(args)+1 ];
2744 strcpy(p, "/c ");
2745 strcat(p, command);
2746 p += strlen(p) + 1;
2747 *p = '\0';
2748
2749 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002750 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002751 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002752 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002753 &rcodes, shell);
2754 return rc;
2755}
2756
Guido van Rossumd48f2521997-12-05 22:19:34 +00002757static FILE *
2758popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002759{
2760 HFILE rhan, whan;
2761 FILE *retfd = NULL;
2762 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2763
Guido van Rossumd48f2521997-12-05 22:19:34 +00002764 if (rc != NO_ERROR) {
2765 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002766 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002767 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002768
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002769 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2770 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002771
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002772 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2773 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002774
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002775 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2776 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002777
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002778 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002779 }
2780
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002781 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2782 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002783
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002784 if (rc == NO_ERROR)
2785 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2786
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002787 close(oldfd); /* And Close Saved STDOUT Handle */
2788 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002789
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002790 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2791 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002792
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002793 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2794 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002795
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002796 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2797 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002798
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002799 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002800 }
2801
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002802 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2803 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002804
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002805 if (rc == NO_ERROR)
2806 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2807
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002808 close(oldfd); /* And Close Saved STDIN Handle */
2809 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002810
Guido van Rossumd48f2521997-12-05 22:19:34 +00002811 } else {
2812 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002813 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002814 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002815}
2816
2817static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002818posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002819{
2820 char *name;
2821 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002822 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002823 FILE *fp;
2824 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002825 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002826 return NULL;
2827 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002828 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002829 Py_END_ALLOW_THREADS
2830 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002831 return os2_error(err);
2832
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002833 f = PyFile_FromFile(fp, name, mode, fclose);
2834 if (f != NULL)
2835 PyFile_SetBufSize(f, bufsize);
2836 return f;
2837}
2838
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002839#elif defined(PYCC_GCC)
2840
2841/* standard posix version of popen() support */
2842static PyObject *
2843posix_popen(PyObject *self, PyObject *args)
2844{
2845 char *name;
2846 char *mode = "r";
2847 int bufsize = -1;
2848 FILE *fp;
2849 PyObject *f;
2850 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2851 return NULL;
2852 Py_BEGIN_ALLOW_THREADS
2853 fp = popen(name, mode);
2854 Py_END_ALLOW_THREADS
2855 if (fp == NULL)
2856 return posix_error();
2857 f = PyFile_FromFile(fp, name, mode, pclose);
2858 if (f != NULL)
2859 PyFile_SetBufSize(f, bufsize);
2860 return f;
2861}
2862
2863/* fork() under OS/2 has lots'o'warts
2864 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2865 * most of this code is a ripoff of the win32 code, but using the
2866 * capabilities of EMX's C library routines
2867 */
2868
2869/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2870#define POPEN_1 1
2871#define POPEN_2 2
2872#define POPEN_3 3
2873#define POPEN_4 4
2874
2875static PyObject *_PyPopen(char *, int, int, int);
2876static int _PyPclose(FILE *file);
2877
2878/*
2879 * Internal dictionary mapping popen* file pointers to process handles,
2880 * for use when retrieving the process exit code. See _PyPclose() below
2881 * for more information on this dictionary's use.
2882 */
2883static PyObject *_PyPopenProcs = NULL;
2884
2885/* os2emx version of popen2()
2886 *
2887 * The result of this function is a pipe (file) connected to the
2888 * process's stdin, and a pipe connected to the process's stdout.
2889 */
2890
2891static PyObject *
2892os2emx_popen2(PyObject *self, PyObject *args)
2893{
2894 PyObject *f;
2895 int tm=0;
2896
2897 char *cmdstring;
2898 char *mode = "t";
2899 int bufsize = -1;
2900 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2901 return NULL;
2902
2903 if (*mode == 't')
2904 tm = O_TEXT;
2905 else if (*mode != 'b') {
2906 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2907 return NULL;
2908 } else
2909 tm = O_BINARY;
2910
2911 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2912
2913 return f;
2914}
2915
2916/*
2917 * Variation on os2emx.popen2
2918 *
2919 * The result of this function is 3 pipes - the process's stdin,
2920 * stdout and stderr
2921 */
2922
2923static PyObject *
2924os2emx_popen3(PyObject *self, PyObject *args)
2925{
2926 PyObject *f;
2927 int tm = 0;
2928
2929 char *cmdstring;
2930 char *mode = "t";
2931 int bufsize = -1;
2932 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2933 return NULL;
2934
2935 if (*mode == 't')
2936 tm = O_TEXT;
2937 else if (*mode != 'b') {
2938 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2939 return NULL;
2940 } else
2941 tm = O_BINARY;
2942
2943 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2944
2945 return f;
2946}
2947
2948/*
2949 * Variation on os2emx.popen2
2950 *
2951 * The result of this function is 2 pipes - the processes stdin,
2952 * and stdout+stderr combined as a single pipe.
2953 */
2954
2955static PyObject *
2956os2emx_popen4(PyObject *self, PyObject *args)
2957{
2958 PyObject *f;
2959 int tm = 0;
2960
2961 char *cmdstring;
2962 char *mode = "t";
2963 int bufsize = -1;
2964 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2965 return NULL;
2966
2967 if (*mode == 't')
2968 tm = O_TEXT;
2969 else if (*mode != 'b') {
2970 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2971 return NULL;
2972 } else
2973 tm = O_BINARY;
2974
2975 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2976
2977 return f;
2978}
2979
2980/* a couple of structures for convenient handling of multiple
2981 * file handles and pipes
2982 */
2983struct file_ref
2984{
2985 int handle;
2986 int flags;
2987};
2988
2989struct pipe_ref
2990{
2991 int rd;
2992 int wr;
2993};
2994
2995/* The following code is derived from the win32 code */
2996
2997static PyObject *
2998_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2999{
3000 struct file_ref stdio[3];
3001 struct pipe_ref p_fd[3];
3002 FILE *p_s[3];
3003 int file_count, i, pipe_err, pipe_pid;
3004 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3005 PyObject *f, *p_f[3];
3006
3007 /* file modes for subsequent fdopen's on pipe handles */
3008 if (mode == O_TEXT)
3009 {
3010 rd_mode = "rt";
3011 wr_mode = "wt";
3012 }
3013 else
3014 {
3015 rd_mode = "rb";
3016 wr_mode = "wb";
3017 }
3018
3019 /* prepare shell references */
3020 if ((shell = getenv("EMXSHELL")) == NULL)
3021 if ((shell = getenv("COMSPEC")) == NULL)
3022 {
3023 errno = ENOENT;
3024 return posix_error();
3025 }
3026
3027 sh_name = _getname(shell);
3028 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3029 opt = "/c";
3030 else
3031 opt = "-c";
3032
3033 /* save current stdio fds + their flags, and set not inheritable */
3034 i = pipe_err = 0;
3035 while (pipe_err >= 0 && i < 3)
3036 {
3037 pipe_err = stdio[i].handle = dup(i);
3038 stdio[i].flags = fcntl(i, F_GETFD, 0);
3039 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3040 i++;
3041 }
3042 if (pipe_err < 0)
3043 {
3044 /* didn't get them all saved - clean up and bail out */
3045 int saved_err = errno;
3046 while (i-- > 0)
3047 {
3048 close(stdio[i].handle);
3049 }
3050 errno = saved_err;
3051 return posix_error();
3052 }
3053
3054 /* create pipe ends */
3055 file_count = 2;
3056 if (n == POPEN_3)
3057 file_count = 3;
3058 i = pipe_err = 0;
3059 while ((pipe_err == 0) && (i < file_count))
3060 pipe_err = pipe((int *)&p_fd[i++]);
3061 if (pipe_err < 0)
3062 {
3063 /* didn't get them all made - clean up and bail out */
3064 while (i-- > 0)
3065 {
3066 close(p_fd[i].wr);
3067 close(p_fd[i].rd);
3068 }
3069 errno = EPIPE;
3070 return posix_error();
3071 }
3072
3073 /* change the actual standard IO streams over temporarily,
3074 * making the retained pipe ends non-inheritable
3075 */
3076 pipe_err = 0;
3077
3078 /* - stdin */
3079 if (dup2(p_fd[0].rd, 0) == 0)
3080 {
3081 close(p_fd[0].rd);
3082 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3083 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3084 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3085 {
3086 close(p_fd[0].wr);
3087 pipe_err = -1;
3088 }
3089 }
3090 else
3091 {
3092 pipe_err = -1;
3093 }
3094
3095 /* - stdout */
3096 if (pipe_err == 0)
3097 {
3098 if (dup2(p_fd[1].wr, 1) == 1)
3099 {
3100 close(p_fd[1].wr);
3101 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3102 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3103 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3104 {
3105 close(p_fd[1].rd);
3106 pipe_err = -1;
3107 }
3108 }
3109 else
3110 {
3111 pipe_err = -1;
3112 }
3113 }
3114
3115 /* - stderr, as required */
3116 if (pipe_err == 0)
3117 switch (n)
3118 {
3119 case POPEN_3:
3120 {
3121 if (dup2(p_fd[2].wr, 2) == 2)
3122 {
3123 close(p_fd[2].wr);
3124 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3125 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3126 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3127 {
3128 close(p_fd[2].rd);
3129 pipe_err = -1;
3130 }
3131 }
3132 else
3133 {
3134 pipe_err = -1;
3135 }
3136 break;
3137 }
3138
3139 case POPEN_4:
3140 {
3141 if (dup2(1, 2) != 2)
3142 {
3143 pipe_err = -1;
3144 }
3145 break;
3146 }
3147 }
3148
3149 /* spawn the child process */
3150 if (pipe_err == 0)
3151 {
3152 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3153 if (pipe_pid == -1)
3154 {
3155 pipe_err = -1;
3156 }
3157 else
3158 {
3159 /* save the PID into the FILE structure
3160 * NOTE: this implementation doesn't actually
3161 * take advantage of this, but do it for
3162 * completeness - AIM Apr01
3163 */
3164 for (i = 0; i < file_count; i++)
3165 p_s[i]->_pid = pipe_pid;
3166 }
3167 }
3168
3169 /* reset standard IO to normal */
3170 for (i = 0; i < 3; i++)
3171 {
3172 dup2(stdio[i].handle, i);
3173 fcntl(i, F_SETFD, stdio[i].flags);
3174 close(stdio[i].handle);
3175 }
3176
3177 /* if any remnant problems, clean up and bail out */
3178 if (pipe_err < 0)
3179 {
3180 for (i = 0; i < 3; i++)
3181 {
3182 close(p_fd[i].rd);
3183 close(p_fd[i].wr);
3184 }
3185 errno = EPIPE;
3186 return posix_error_with_filename(cmdstring);
3187 }
3188
3189 /* build tuple of file objects to return */
3190 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3191 PyFile_SetBufSize(p_f[0], bufsize);
3192 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3193 PyFile_SetBufSize(p_f[1], bufsize);
3194 if (n == POPEN_3)
3195 {
3196 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3197 PyFile_SetBufSize(p_f[0], bufsize);
3198 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3199 }
3200 else
3201 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3202
3203 /*
3204 * Insert the files we've created into the process dictionary
3205 * all referencing the list with the process handle and the
3206 * initial number of files (see description below in _PyPclose).
3207 * Since if _PyPclose later tried to wait on a process when all
3208 * handles weren't closed, it could create a deadlock with the
3209 * child, we spend some energy here to try to ensure that we
3210 * either insert all file handles into the dictionary or none
3211 * at all. It's a little clumsy with the various popen modes
3212 * and variable number of files involved.
3213 */
3214 if (!_PyPopenProcs)
3215 {
3216 _PyPopenProcs = PyDict_New();
3217 }
3218
3219 if (_PyPopenProcs)
3220 {
3221 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3222 int ins_rc[3];
3223
3224 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3225 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3226
3227 procObj = PyList_New(2);
3228 pidObj = PyInt_FromLong((long) pipe_pid);
3229 intObj = PyInt_FromLong((long) file_count);
3230
3231 if (procObj && pidObj && intObj)
3232 {
3233 PyList_SetItem(procObj, 0, pidObj);
3234 PyList_SetItem(procObj, 1, intObj);
3235
3236 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3237 if (fileObj[0])
3238 {
3239 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3240 fileObj[0],
3241 procObj);
3242 }
3243 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3244 if (fileObj[1])
3245 {
3246 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3247 fileObj[1],
3248 procObj);
3249 }
3250 if (file_count >= 3)
3251 {
3252 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3253 if (fileObj[2])
3254 {
3255 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3256 fileObj[2],
3257 procObj);
3258 }
3259 }
3260
3261 if (ins_rc[0] < 0 || !fileObj[0] ||
3262 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3263 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3264 {
3265 /* Something failed - remove any dictionary
3266 * entries that did make it.
3267 */
3268 if (!ins_rc[0] && fileObj[0])
3269 {
3270 PyDict_DelItem(_PyPopenProcs,
3271 fileObj[0]);
3272 }
3273 if (!ins_rc[1] && fileObj[1])
3274 {
3275 PyDict_DelItem(_PyPopenProcs,
3276 fileObj[1]);
3277 }
3278 if (!ins_rc[2] && fileObj[2])
3279 {
3280 PyDict_DelItem(_PyPopenProcs,
3281 fileObj[2]);
3282 }
3283 }
3284 }
3285
3286 /*
3287 * Clean up our localized references for the dictionary keys
3288 * and value since PyDict_SetItem will Py_INCREF any copies
3289 * that got placed in the dictionary.
3290 */
3291 Py_XDECREF(procObj);
3292 Py_XDECREF(fileObj[0]);
3293 Py_XDECREF(fileObj[1]);
3294 Py_XDECREF(fileObj[2]);
3295 }
3296
3297 /* Child is launched. */
3298 return f;
3299}
3300
3301/*
3302 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3303 * exit code for the child process and return as a result of the close.
3304 *
3305 * This function uses the _PyPopenProcs dictionary in order to map the
3306 * input file pointer to information about the process that was
3307 * originally created by the popen* call that created the file pointer.
3308 * The dictionary uses the file pointer as a key (with one entry
3309 * inserted for each file returned by the original popen* call) and a
3310 * single list object as the value for all files from a single call.
3311 * The list object contains the Win32 process handle at [0], and a file
3312 * count at [1], which is initialized to the total number of file
3313 * handles using that list.
3314 *
3315 * This function closes whichever handle it is passed, and decrements
3316 * the file count in the dictionary for the process handle pointed to
3317 * by this file. On the last close (when the file count reaches zero),
3318 * this function will wait for the child process and then return its
3319 * exit code as the result of the close() operation. This permits the
3320 * files to be closed in any order - it is always the close() of the
3321 * final handle that will return the exit code.
3322 */
3323
3324 /* RED_FLAG 31-Aug-2000 Tim
3325 * This is always called (today!) between a pair of
3326 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3327 * macros. So the thread running this has no valid thread state, as
3328 * far as Python is concerned. However, this calls some Python API
3329 * functions that cannot be called safely without a valid thread
3330 * state, in particular PyDict_GetItem.
3331 * As a temporary hack (although it may last for years ...), we
3332 * *rely* on not having a valid thread state in this function, in
3333 * order to create our own "from scratch".
3334 * This will deadlock if _PyPclose is ever called by a thread
3335 * holding the global lock.
3336 * (The OS/2 EMX thread support appears to cover the case where the
3337 * lock is already held - AIM Apr01)
3338 */
3339
3340static int _PyPclose(FILE *file)
3341{
3342 int result;
3343 int exit_code;
3344 int pipe_pid;
3345 PyObject *procObj, *pidObj, *intObj, *fileObj;
3346 int file_count;
3347#ifdef WITH_THREAD
3348 PyInterpreterState* pInterpreterState;
3349 PyThreadState* pThreadState;
3350#endif
3351
3352 /* Close the file handle first, to ensure it can't block the
3353 * child from exiting if it's the last handle.
3354 */
3355 result = fclose(file);
3356
3357#ifdef WITH_THREAD
3358 /* Bootstrap a valid thread state into existence. */
3359 pInterpreterState = PyInterpreterState_New();
3360 if (!pInterpreterState) {
3361 /* Well, we're hosed now! We don't have a thread
3362 * state, so can't call a nice error routine, or raise
3363 * an exception. Just die.
3364 */
3365 Py_FatalError("unable to allocate interpreter state "
3366 "when closing popen object.");
3367 return -1; /* unreachable */
3368 }
3369 pThreadState = PyThreadState_New(pInterpreterState);
3370 if (!pThreadState) {
3371 Py_FatalError("unable to allocate thread state "
3372 "when closing popen object.");
3373 return -1; /* unreachable */
3374 }
3375 /* Grab the global lock. Note that this will deadlock if the
3376 * current thread already has the lock! (see RED_FLAG comments
3377 * before this function)
3378 */
3379 PyEval_RestoreThread(pThreadState);
3380#endif
3381
3382 if (_PyPopenProcs)
3383 {
3384 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3385 (procObj = PyDict_GetItem(_PyPopenProcs,
3386 fileObj)) != NULL &&
3387 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3388 (intObj = PyList_GetItem(procObj,1)) != NULL)
3389 {
3390 pipe_pid = (int) PyInt_AsLong(pidObj);
3391 file_count = (int) PyInt_AsLong(intObj);
3392
3393 if (file_count > 1)
3394 {
3395 /* Still other files referencing process */
3396 file_count--;
3397 PyList_SetItem(procObj,1,
3398 PyInt_FromLong((long) file_count));
3399 }
3400 else
3401 {
3402 /* Last file for this process */
3403 if (result != EOF &&
3404 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3405 {
3406 /* extract exit status */
3407 if (WIFEXITED(exit_code))
3408 {
3409 result = WEXITSTATUS(exit_code);
3410 }
3411 else
3412 {
3413 errno = EPIPE;
3414 result = -1;
3415 }
3416 }
3417 else
3418 {
3419 /* Indicate failure - this will cause the file object
3420 * to raise an I/O error and translate the last
3421 * error code from errno. We do have a problem with
3422 * last errors that overlap the normal errno table,
3423 * but that's a consistent problem with the file object.
3424 */
3425 result = -1;
3426 }
3427 }
3428
3429 /* Remove this file pointer from dictionary */
3430 PyDict_DelItem(_PyPopenProcs, fileObj);
3431
3432 if (PyDict_Size(_PyPopenProcs) == 0)
3433 {
3434 Py_DECREF(_PyPopenProcs);
3435 _PyPopenProcs = NULL;
3436 }
3437
3438 } /* if object retrieval ok */
3439
3440 Py_XDECREF(fileObj);
3441 } /* if _PyPopenProcs */
3442
3443#ifdef WITH_THREAD
3444 /* Tear down the thread & interpreter states.
3445 * Note that interpreter state clear & delete functions automatically
3446 * call the thread clear & delete functions, and indeed insist on
3447 * doing that themselves. The lock must be held during the clear, but
3448 * need not be held during the delete.
3449 */
3450 PyInterpreterState_Clear(pInterpreterState);
3451 PyEval_ReleaseThread(pThreadState);
3452 PyInterpreterState_Delete(pInterpreterState);
3453#endif
3454
3455 return result;
3456}
3457
3458#endif /* PYCC_??? */
3459
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003460#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003461
3462/*
3463 * Portable 'popen' replacement for Win32.
3464 *
3465 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3466 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003467 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003468 */
3469
3470#include <malloc.h>
3471#include <io.h>
3472#include <fcntl.h>
3473
3474/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3475#define POPEN_1 1
3476#define POPEN_2 2
3477#define POPEN_3 3
3478#define POPEN_4 4
3479
3480static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003481static int _PyPclose(FILE *file);
3482
3483/*
3484 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003485 * for use when retrieving the process exit code. See _PyPclose() below
3486 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003487 */
3488static PyObject *_PyPopenProcs = NULL;
3489
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003490
3491/* popen that works from a GUI.
3492 *
3493 * The result of this function is a pipe (file) connected to the
3494 * processes stdin or stdout, depending on the requested mode.
3495 */
3496
3497static PyObject *
3498posix_popen(PyObject *self, PyObject *args)
3499{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003500 PyObject *f, *s;
3501 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003502
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003503 char *cmdstring;
3504 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003505 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003506 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003507 return NULL;
3508
3509 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003510
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003511 if (*mode == 'r')
3512 tm = _O_RDONLY;
3513 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003514 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003515 return NULL;
3516 } else
3517 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003518
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003519 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003520 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003521 return NULL;
3522 }
3523
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003524 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003525 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003526 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003527 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003528 else
3529 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3530
3531 return f;
3532}
3533
3534/* Variation on win32pipe.popen
3535 *
3536 * The result of this function is a pipe (file) connected to the
3537 * process's stdin, and a pipe connected to the process's stdout.
3538 */
3539
3540static PyObject *
3541win32_popen2(PyObject *self, PyObject *args)
3542{
3543 PyObject *f;
3544 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003545
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003546 char *cmdstring;
3547 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003548 int bufsize = -1;
3549 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003550 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003551
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003552 if (*mode == 't')
3553 tm = _O_TEXT;
3554 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003555 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003556 return NULL;
3557 } else
3558 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003559
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003560 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003561 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003562 return NULL;
3563 }
3564
3565 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003566
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003567 return f;
3568}
3569
3570/*
3571 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003572 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003573 * The result of this function is 3 pipes - the process's stdin,
3574 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003575 */
3576
3577static PyObject *
3578win32_popen3(PyObject *self, PyObject *args)
3579{
3580 PyObject *f;
3581 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003582
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003583 char *cmdstring;
3584 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003585 int bufsize = -1;
3586 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003587 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003588
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003589 if (*mode == 't')
3590 tm = _O_TEXT;
3591 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003592 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003593 return NULL;
3594 } else
3595 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003596
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003597 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003598 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003599 return NULL;
3600 }
3601
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003602 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003603
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003604 return f;
3605}
3606
3607/*
3608 * Variation on win32pipe.popen
3609 *
Tim Peters5aa91602002-01-30 05:46:57 +00003610 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003611 * and stdout+stderr combined as a single pipe.
3612 */
3613
3614static PyObject *
3615win32_popen4(PyObject *self, PyObject *args)
3616{
3617 PyObject *f;
3618 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003619
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003620 char *cmdstring;
3621 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003622 int bufsize = -1;
3623 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003624 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003625
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003626 if (*mode == 't')
3627 tm = _O_TEXT;
3628 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003629 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003630 return NULL;
3631 } else
3632 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003633
3634 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003635 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003636 return NULL;
3637 }
3638
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003639 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003640
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003641 return f;
3642}
3643
Mark Hammond08501372001-01-31 07:30:29 +00003644static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003645_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003646 HANDLE hStdin,
3647 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003648 HANDLE hStderr,
3649 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003650{
3651 PROCESS_INFORMATION piProcInfo;
3652 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003653 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003654 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003655 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003656 int i;
3657 int x;
3658
3659 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003660 char *comshell;
3661
Tim Peters92e4dd82002-10-05 01:47:34 +00003662 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003663 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3664 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003665
3666 /* Explicitly check if we are using COMMAND.COM. If we are
3667 * then use the w9xpopen hack.
3668 */
3669 comshell = s1 + x;
3670 while (comshell >= s1 && *comshell != '\\')
3671 --comshell;
3672 ++comshell;
3673
3674 if (GetVersion() < 0x80000000 &&
3675 _stricmp(comshell, "command.com") != 0) {
3676 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003677 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003678 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003679 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003680 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003681 }
3682 else {
3683 /*
Tim Peters402d5982001-08-27 06:37:48 +00003684 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3685 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003686 */
Mark Hammond08501372001-01-31 07:30:29 +00003687 char modulepath[_MAX_PATH];
3688 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003689 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3690 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003691 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003692 x = i+1;
3693 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003694 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003695 strncat(modulepath,
3696 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003697 (sizeof(modulepath)/sizeof(modulepath[0]))
3698 -strlen(modulepath));
3699 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003700 /* Eeek - file-not-found - possibly an embedding
3701 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003702 */
Tim Peters5aa91602002-01-30 05:46:57 +00003703 strncpy(modulepath,
3704 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003705 sizeof(modulepath)/sizeof(modulepath[0]));
3706 if (modulepath[strlen(modulepath)-1] != '\\')
3707 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003708 strncat(modulepath,
3709 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003710 (sizeof(modulepath)/sizeof(modulepath[0]))
3711 -strlen(modulepath));
3712 /* No where else to look - raise an easily identifiable
3713 error, rather than leaving Windows to report
3714 "file not found" - as the user is probably blissfully
3715 unaware this shim EXE is used, and it will confuse them.
3716 (well, it confused me for a while ;-)
3717 */
3718 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003719 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003720 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003721 "for popen to work with your shell "
3722 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003723 szConsoleSpawn);
3724 return FALSE;
3725 }
3726 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003727 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003728 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003729 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003730
Tim Peters92e4dd82002-10-05 01:47:34 +00003731 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003732 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003733 /* To maintain correct argument passing semantics,
3734 we pass the command-line as it stands, and allow
3735 quoting to be applied. w9xpopen.exe will then
3736 use its argv vector, and re-quote the necessary
3737 args for the ultimate child process.
3738 */
Tim Peters75cdad52001-11-28 22:07:30 +00003739 PyOS_snprintf(
3740 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003741 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003742 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003743 s1,
3744 s3,
3745 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003746 /* Not passing CREATE_NEW_CONSOLE has been known to
3747 cause random failures on win9x. Specifically a
3748 dialog:
3749 "Your program accessed mem currently in use at xxx"
3750 and a hopeful warning about the stability of your
3751 system.
3752 Cost is Ctrl+C wont kill children, but anyone
3753 who cares can have a go!
3754 */
3755 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003756 }
3757 }
3758
3759 /* Could be an else here to try cmd.exe / command.com in the path
3760 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003761 else {
Tim Peters402d5982001-08-27 06:37:48 +00003762 PyErr_SetString(PyExc_RuntimeError,
3763 "Cannot locate a COMSPEC environment variable to "
3764 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003765 return FALSE;
3766 }
Tim Peters5aa91602002-01-30 05:46:57 +00003767
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003768 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3769 siStartInfo.cb = sizeof(STARTUPINFO);
3770 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3771 siStartInfo.hStdInput = hStdin;
3772 siStartInfo.hStdOutput = hStdout;
3773 siStartInfo.hStdError = hStderr;
3774 siStartInfo.wShowWindow = SW_HIDE;
3775
3776 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003777 s2,
3778 NULL,
3779 NULL,
3780 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003781 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003782 NULL,
3783 NULL,
3784 &siStartInfo,
3785 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003786 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003787 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003788
Mark Hammondb37a3732000-08-14 04:47:33 +00003789 /* Return process handle */
3790 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003791 return TRUE;
3792 }
Tim Peters402d5982001-08-27 06:37:48 +00003793 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003794 return FALSE;
3795}
3796
3797/* The following code is based off of KB: Q190351 */
3798
3799static PyObject *
3800_PyPopen(char *cmdstring, int mode, int n)
3801{
3802 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3803 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003804 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003805
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003806 SECURITY_ATTRIBUTES saAttr;
3807 BOOL fSuccess;
3808 int fd1, fd2, fd3;
3809 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003810 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003811 PyObject *f;
3812
3813 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3814 saAttr.bInheritHandle = TRUE;
3815 saAttr.lpSecurityDescriptor = NULL;
3816
3817 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3818 return win32_error("CreatePipe", NULL);
3819
3820 /* Create new output read handle and the input write handle. Set
3821 * the inheritance properties to FALSE. Otherwise, the child inherits
3822 * the these handles; resulting in non-closeable handles to the pipes
3823 * being created. */
3824 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003825 GetCurrentProcess(), &hChildStdinWrDup, 0,
3826 FALSE,
3827 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003828 if (!fSuccess)
3829 return win32_error("DuplicateHandle", NULL);
3830
3831 /* Close the inheritable version of ChildStdin
3832 that we're using. */
3833 CloseHandle(hChildStdinWr);
3834
3835 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3836 return win32_error("CreatePipe", NULL);
3837
3838 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003839 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3840 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003841 if (!fSuccess)
3842 return win32_error("DuplicateHandle", NULL);
3843
3844 /* Close the inheritable version of ChildStdout
3845 that we're using. */
3846 CloseHandle(hChildStdoutRd);
3847
3848 if (n != POPEN_4) {
3849 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3850 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003851 fSuccess = DuplicateHandle(GetCurrentProcess(),
3852 hChildStderrRd,
3853 GetCurrentProcess(),
3854 &hChildStderrRdDup, 0,
3855 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003856 if (!fSuccess)
3857 return win32_error("DuplicateHandle", NULL);
3858 /* Close the inheritable version of ChildStdErr that we're using. */
3859 CloseHandle(hChildStderrRd);
3860 }
Tim Peters5aa91602002-01-30 05:46:57 +00003861
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003862 switch (n) {
3863 case POPEN_1:
3864 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3865 case _O_WRONLY | _O_TEXT:
3866 /* Case for writing to child Stdin in text mode. */
3867 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3868 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003869 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003870 PyFile_SetBufSize(f, 0);
3871 /* We don't care about these pipes anymore, so close them. */
3872 CloseHandle(hChildStdoutRdDup);
3873 CloseHandle(hChildStderrRdDup);
3874 break;
3875
3876 case _O_RDONLY | _O_TEXT:
3877 /* Case for reading from child Stdout in text mode. */
3878 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3879 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003880 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003881 PyFile_SetBufSize(f, 0);
3882 /* We don't care about these pipes anymore, so close them. */
3883 CloseHandle(hChildStdinWrDup);
3884 CloseHandle(hChildStderrRdDup);
3885 break;
3886
3887 case _O_RDONLY | _O_BINARY:
3888 /* Case for readinig from child Stdout in binary mode. */
3889 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3890 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003891 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003892 PyFile_SetBufSize(f, 0);
3893 /* We don't care about these pipes anymore, so close them. */
3894 CloseHandle(hChildStdinWrDup);
3895 CloseHandle(hChildStderrRdDup);
3896 break;
3897
3898 case _O_WRONLY | _O_BINARY:
3899 /* Case for writing to child Stdin in binary mode. */
3900 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3901 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003902 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003903 PyFile_SetBufSize(f, 0);
3904 /* We don't care about these pipes anymore, so close them. */
3905 CloseHandle(hChildStdoutRdDup);
3906 CloseHandle(hChildStderrRdDup);
3907 break;
3908 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003909 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003910 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003911
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003912 case POPEN_2:
3913 case POPEN_4:
3914 {
3915 char *m1, *m2;
3916 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003917
Tim Peters7dca21e2002-08-19 00:42:29 +00003918 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003919 m1 = "r";
3920 m2 = "w";
3921 } else {
3922 m1 = "rb";
3923 m2 = "wb";
3924 }
3925
3926 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3927 f1 = _fdopen(fd1, m2);
3928 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3929 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003930 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003931 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003932 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003933 PyFile_SetBufSize(p2, 0);
3934
3935 if (n != 4)
3936 CloseHandle(hChildStderrRdDup);
3937
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003938 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003939 Py_XDECREF(p1);
3940 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003941 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003942 break;
3943 }
Tim Peters5aa91602002-01-30 05:46:57 +00003944
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003945 case POPEN_3:
3946 {
3947 char *m1, *m2;
3948 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003949
Tim Peters7dca21e2002-08-19 00:42:29 +00003950 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003951 m1 = "r";
3952 m2 = "w";
3953 } else {
3954 m1 = "rb";
3955 m2 = "wb";
3956 }
3957
3958 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3959 f1 = _fdopen(fd1, m2);
3960 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3961 f2 = _fdopen(fd2, m1);
3962 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3963 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003964 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003965 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3966 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003967 PyFile_SetBufSize(p1, 0);
3968 PyFile_SetBufSize(p2, 0);
3969 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003970 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003971 Py_XDECREF(p1);
3972 Py_XDECREF(p2);
3973 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003974 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003975 break;
3976 }
3977 }
3978
3979 if (n == POPEN_4) {
3980 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003981 hChildStdinRd,
3982 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003983 hChildStdoutWr,
3984 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003985 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003986 }
3987 else {
3988 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003989 hChildStdinRd,
3990 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003991 hChildStderrWr,
3992 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003993 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003994 }
3995
Mark Hammondb37a3732000-08-14 04:47:33 +00003996 /*
3997 * Insert the files we've created into the process dictionary
3998 * all referencing the list with the process handle and the
3999 * initial number of files (see description below in _PyPclose).
4000 * Since if _PyPclose later tried to wait on a process when all
4001 * handles weren't closed, it could create a deadlock with the
4002 * child, we spend some energy here to try to ensure that we
4003 * either insert all file handles into the dictionary or none
4004 * at all. It's a little clumsy with the various popen modes
4005 * and variable number of files involved.
4006 */
4007 if (!_PyPopenProcs) {
4008 _PyPopenProcs = PyDict_New();
4009 }
4010
4011 if (_PyPopenProcs) {
4012 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4013 int ins_rc[3];
4014
4015 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4016 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4017
4018 procObj = PyList_New(2);
4019 hProcessObj = PyLong_FromVoidPtr(hProcess);
4020 intObj = PyInt_FromLong(file_count);
4021
4022 if (procObj && hProcessObj && intObj) {
4023 PyList_SetItem(procObj,0,hProcessObj);
4024 PyList_SetItem(procObj,1,intObj);
4025
4026 fileObj[0] = PyLong_FromVoidPtr(f1);
4027 if (fileObj[0]) {
4028 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4029 fileObj[0],
4030 procObj);
4031 }
4032 if (file_count >= 2) {
4033 fileObj[1] = PyLong_FromVoidPtr(f2);
4034 if (fileObj[1]) {
4035 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4036 fileObj[1],
4037 procObj);
4038 }
4039 }
4040 if (file_count >= 3) {
4041 fileObj[2] = PyLong_FromVoidPtr(f3);
4042 if (fileObj[2]) {
4043 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4044 fileObj[2],
4045 procObj);
4046 }
4047 }
4048
4049 if (ins_rc[0] < 0 || !fileObj[0] ||
4050 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4051 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4052 /* Something failed - remove any dictionary
4053 * entries that did make it.
4054 */
4055 if (!ins_rc[0] && fileObj[0]) {
4056 PyDict_DelItem(_PyPopenProcs,
4057 fileObj[0]);
4058 }
4059 if (!ins_rc[1] && fileObj[1]) {
4060 PyDict_DelItem(_PyPopenProcs,
4061 fileObj[1]);
4062 }
4063 if (!ins_rc[2] && fileObj[2]) {
4064 PyDict_DelItem(_PyPopenProcs,
4065 fileObj[2]);
4066 }
4067 }
4068 }
Tim Peters5aa91602002-01-30 05:46:57 +00004069
Mark Hammondb37a3732000-08-14 04:47:33 +00004070 /*
4071 * Clean up our localized references for the dictionary keys
4072 * and value since PyDict_SetItem will Py_INCREF any copies
4073 * that got placed in the dictionary.
4074 */
4075 Py_XDECREF(procObj);
4076 Py_XDECREF(fileObj[0]);
4077 Py_XDECREF(fileObj[1]);
4078 Py_XDECREF(fileObj[2]);
4079 }
4080
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004081 /* Child is launched. Close the parents copy of those pipe
4082 * handles that only the child should have open. You need to
4083 * make sure that no handles to the write end of the output pipe
4084 * are maintained in this process or else the pipe will not close
4085 * when the child process exits and the ReadFile will hang. */
4086
4087 if (!CloseHandle(hChildStdinRd))
4088 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004089
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004090 if (!CloseHandle(hChildStdoutWr))
4091 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004092
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004093 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4094 return win32_error("CloseHandle", NULL);
4095
4096 return f;
4097}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004098
4099/*
4100 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4101 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004102 *
4103 * This function uses the _PyPopenProcs dictionary in order to map the
4104 * input file pointer to information about the process that was
4105 * originally created by the popen* call that created the file pointer.
4106 * The dictionary uses the file pointer as a key (with one entry
4107 * inserted for each file returned by the original popen* call) and a
4108 * single list object as the value for all files from a single call.
4109 * The list object contains the Win32 process handle at [0], and a file
4110 * count at [1], which is initialized to the total number of file
4111 * handles using that list.
4112 *
4113 * This function closes whichever handle it is passed, and decrements
4114 * the file count in the dictionary for the process handle pointed to
4115 * by this file. On the last close (when the file count reaches zero),
4116 * this function will wait for the child process and then return its
4117 * exit code as the result of the close() operation. This permits the
4118 * files to be closed in any order - it is always the close() of the
4119 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004120 */
Tim Peters736aa322000-09-01 06:51:24 +00004121
4122 /* RED_FLAG 31-Aug-2000 Tim
4123 * This is always called (today!) between a pair of
4124 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4125 * macros. So the thread running this has no valid thread state, as
4126 * far as Python is concerned. However, this calls some Python API
4127 * functions that cannot be called safely without a valid thread
4128 * state, in particular PyDict_GetItem.
4129 * As a temporary hack (although it may last for years ...), we
4130 * *rely* on not having a valid thread state in this function, in
4131 * order to create our own "from scratch".
4132 * This will deadlock if _PyPclose is ever called by a thread
4133 * holding the global lock.
4134 */
4135
Fredrik Lundh56055a42000-07-23 19:47:12 +00004136static int _PyPclose(FILE *file)
4137{
Fredrik Lundh20318932000-07-26 17:29:12 +00004138 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004139 DWORD exit_code;
4140 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004141 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4142 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004143#ifdef WITH_THREAD
4144 PyInterpreterState* pInterpreterState;
4145 PyThreadState* pThreadState;
4146#endif
4147
Fredrik Lundh20318932000-07-26 17:29:12 +00004148 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004149 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004150 */
4151 result = fclose(file);
4152
Tim Peters736aa322000-09-01 06:51:24 +00004153#ifdef WITH_THREAD
4154 /* Bootstrap a valid thread state into existence. */
4155 pInterpreterState = PyInterpreterState_New();
4156 if (!pInterpreterState) {
4157 /* Well, we're hosed now! We don't have a thread
4158 * state, so can't call a nice error routine, or raise
4159 * an exception. Just die.
4160 */
4161 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004162 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004163 return -1; /* unreachable */
4164 }
4165 pThreadState = PyThreadState_New(pInterpreterState);
4166 if (!pThreadState) {
4167 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004168 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004169 return -1; /* unreachable */
4170 }
4171 /* Grab the global lock. Note that this will deadlock if the
4172 * current thread already has the lock! (see RED_FLAG comments
4173 * before this function)
4174 */
4175 PyEval_RestoreThread(pThreadState);
4176#endif
4177
Fredrik Lundh56055a42000-07-23 19:47:12 +00004178 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004179 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4180 (procObj = PyDict_GetItem(_PyPopenProcs,
4181 fileObj)) != NULL &&
4182 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4183 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4184
4185 hProcess = PyLong_AsVoidPtr(hProcessObj);
4186 file_count = PyInt_AsLong(intObj);
4187
4188 if (file_count > 1) {
4189 /* Still other files referencing process */
4190 file_count--;
4191 PyList_SetItem(procObj,1,
4192 PyInt_FromLong(file_count));
4193 } else {
4194 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004195 if (result != EOF &&
4196 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4197 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004198 /* Possible truncation here in 16-bit environments, but
4199 * real exit codes are just the lower byte in any event.
4200 */
4201 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004202 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004203 /* Indicate failure - this will cause the file object
4204 * to raise an I/O error and translate the last Win32
4205 * error code from errno. We do have a problem with
4206 * last errors that overlap the normal errno table,
4207 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004208 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004209 if (result != EOF) {
4210 /* If the error wasn't from the fclose(), then
4211 * set errno for the file object error handling.
4212 */
4213 errno = GetLastError();
4214 }
4215 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004216 }
4217
4218 /* Free up the native handle at this point */
4219 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004220 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004221
Mark Hammondb37a3732000-08-14 04:47:33 +00004222 /* Remove this file pointer from dictionary */
4223 PyDict_DelItem(_PyPopenProcs, fileObj);
4224
4225 if (PyDict_Size(_PyPopenProcs) == 0) {
4226 Py_DECREF(_PyPopenProcs);
4227 _PyPopenProcs = NULL;
4228 }
4229
4230 } /* if object retrieval ok */
4231
4232 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004233 } /* if _PyPopenProcs */
4234
Tim Peters736aa322000-09-01 06:51:24 +00004235#ifdef WITH_THREAD
4236 /* Tear down the thread & interpreter states.
4237 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004238 * call the thread clear & delete functions, and indeed insist on
4239 * doing that themselves. The lock must be held during the clear, but
4240 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004241 */
4242 PyInterpreterState_Clear(pInterpreterState);
4243 PyEval_ReleaseThread(pThreadState);
4244 PyInterpreterState_Delete(pInterpreterState);
4245#endif
4246
Fredrik Lundh56055a42000-07-23 19:47:12 +00004247 return result;
4248}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004249
4250#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004252posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004253{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004254 char *name;
4255 char *mode = "r";
4256 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004257 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004258 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004259 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004260 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004261 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004262 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004263 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004264 if (fp == NULL)
4265 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004266 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004267 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004268 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004269 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004270}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004271
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004272#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004273#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004275
Guido van Rossumb6775db1994-08-01 11:34:53 +00004276#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004277PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004278"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004279Set the current process's user id.");
4280
Barry Warsaw53699e91996-12-10 23:23:01 +00004281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004282posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004283{
4284 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004285 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004286 return NULL;
4287 if (setuid(uid) < 0)
4288 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004289 Py_INCREF(Py_None);
4290 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004291}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004292#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004294
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004295#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004296PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004297"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004298Set the current process's effective user id.");
4299
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004300static PyObject *
4301posix_seteuid (PyObject *self, PyObject *args)
4302{
4303 int euid;
4304 if (!PyArg_ParseTuple(args, "i", &euid)) {
4305 return NULL;
4306 } else if (seteuid(euid) < 0) {
4307 return posix_error();
4308 } else {
4309 Py_INCREF(Py_None);
4310 return Py_None;
4311 }
4312}
4313#endif /* HAVE_SETEUID */
4314
4315#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004316PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004317"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004318Set the current process's effective group id.");
4319
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004320static PyObject *
4321posix_setegid (PyObject *self, PyObject *args)
4322{
4323 int egid;
4324 if (!PyArg_ParseTuple(args, "i", &egid)) {
4325 return NULL;
4326 } else if (setegid(egid) < 0) {
4327 return posix_error();
4328 } else {
4329 Py_INCREF(Py_None);
4330 return Py_None;
4331 }
4332}
4333#endif /* HAVE_SETEGID */
4334
4335#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004336PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004337"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004338Set the current process's real and effective user ids.");
4339
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004340static PyObject *
4341posix_setreuid (PyObject *self, PyObject *args)
4342{
4343 int ruid, euid;
4344 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4345 return NULL;
4346 } else if (setreuid(ruid, euid) < 0) {
4347 return posix_error();
4348 } else {
4349 Py_INCREF(Py_None);
4350 return Py_None;
4351 }
4352}
4353#endif /* HAVE_SETREUID */
4354
4355#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004356PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004357"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004358Set the current process's real and effective group ids.");
4359
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004360static PyObject *
4361posix_setregid (PyObject *self, PyObject *args)
4362{
4363 int rgid, egid;
4364 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4365 return NULL;
4366 } else if (setregid(rgid, egid) < 0) {
4367 return posix_error();
4368 } else {
4369 Py_INCREF(Py_None);
4370 return Py_None;
4371 }
4372}
4373#endif /* HAVE_SETREGID */
4374
Guido van Rossumb6775db1994-08-01 11:34:53 +00004375#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004376PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004377"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004378Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004379
Barry Warsaw53699e91996-12-10 23:23:01 +00004380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004381posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004382{
4383 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004384 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004385 return NULL;
4386 if (setgid(gid) < 0)
4387 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004388 Py_INCREF(Py_None);
4389 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004390}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004391#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004392
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004393#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004394PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004395"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004396Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004397
4398static PyObject *
4399posix_setgroups(PyObject *self, PyObject *args)
4400{
4401 PyObject *groups;
4402 int i, len;
4403 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004404
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004405 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4406 return NULL;
4407 if (!PySequence_Check(groups)) {
4408 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4409 return NULL;
4410 }
4411 len = PySequence_Size(groups);
4412 if (len > MAX_GROUPS) {
4413 PyErr_SetString(PyExc_ValueError, "too many groups");
4414 return NULL;
4415 }
4416 for(i = 0; i < len; i++) {
4417 PyObject *elem;
4418 elem = PySequence_GetItem(groups, i);
4419 if (!elem)
4420 return NULL;
4421 if (!PyInt_Check(elem)) {
4422 PyErr_SetString(PyExc_TypeError,
4423 "groups must be integers");
4424 Py_DECREF(elem);
4425 return NULL;
4426 }
4427 /* XXX: check that value fits into gid_t. */
4428 grouplist[i] = PyInt_AsLong(elem);
4429 Py_DECREF(elem);
4430 }
4431
4432 if (setgroups(len, grouplist) < 0)
4433 return posix_error();
4434 Py_INCREF(Py_None);
4435 return Py_None;
4436}
4437#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004438
Guido van Rossumb6775db1994-08-01 11:34:53 +00004439#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004440PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004441"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004443
Barry Warsaw53699e91996-12-10 23:23:01 +00004444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004445posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004446{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004447 int pid, options;
4448#ifdef UNION_WAIT
4449 union wait status;
4450#define status_i (status.w_status)
4451#else
4452 int status;
4453#define status_i status
4454#endif
4455 status_i = 0;
4456
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004457 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004458 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004459 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004460 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004461 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004462 if (pid == -1)
4463 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004464 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004465 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004466}
4467
Tim Petersab034fa2002-02-01 11:27:43 +00004468#elif defined(HAVE_CWAIT)
4469
4470/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004471PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004472"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004473"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004474
4475static PyObject *
4476posix_waitpid(PyObject *self, PyObject *args)
4477{
4478 int pid, options;
4479 int status;
4480
4481 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4482 return NULL;
4483 Py_BEGIN_ALLOW_THREADS
4484 pid = _cwait(&status, pid, options);
4485 Py_END_ALLOW_THREADS
4486 if (pid == -1)
4487 return posix_error();
4488 else
4489 /* shift the status left a byte so this is more like the
4490 POSIX waitpid */
4491 return Py_BuildValue("ii", pid, status << 8);
4492}
4493#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004494
Guido van Rossumad0ee831995-03-01 10:34:45 +00004495#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004496PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004497"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004498Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004499
Barry Warsaw53699e91996-12-10 23:23:01 +00004500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004501posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004502{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004503 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004504#ifdef UNION_WAIT
4505 union wait status;
4506#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004507#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004508 int status;
4509#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004510#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004511 if (!PyArg_ParseTuple(args, ":wait"))
4512 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004513 status_i = 0;
4514 Py_BEGIN_ALLOW_THREADS
4515 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004516 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004517 if (pid == -1)
4518 return posix_error();
4519 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004520 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004521#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004522}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004523#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004524
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004526PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004527"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004528Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004529
Barry Warsaw53699e91996-12-10 23:23:01 +00004530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004531posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004532{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004533#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004534 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004535#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004536#ifdef MS_WINDOWS
4537 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4538#else
4539 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4540#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004541#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004542}
4543
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004544
Guido van Rossumb6775db1994-08-01 11:34:53 +00004545#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004546PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004547"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004548Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004549
Barry Warsaw53699e91996-12-10 23:23:01 +00004550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004551posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004552{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004553 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004554 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004555 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004556 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004557 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004558 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004559 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004560 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004561 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004562 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004563 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004564}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004565#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004566
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004567
Guido van Rossumb6775db1994-08-01 11:34:53 +00004568#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004569PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004570"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004571Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004572
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004574posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004575{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004576 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004577}
4578#endif /* HAVE_SYMLINK */
4579
4580
4581#ifdef HAVE_TIMES
4582#ifndef HZ
4583#define HZ 60 /* Universal constant :-) */
4584#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004585
Guido van Rossumd48f2521997-12-05 22:19:34 +00004586#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4587static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004588system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004589{
4590 ULONG value = 0;
4591
4592 Py_BEGIN_ALLOW_THREADS
4593 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4594 Py_END_ALLOW_THREADS
4595
4596 return value;
4597}
4598
4599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004600posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004601{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004602 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004603 return NULL;
4604
4605 /* Currently Only Uptime is Provided -- Others Later */
4606 return Py_BuildValue("ddddd",
4607 (double)0 /* t.tms_utime / HZ */,
4608 (double)0 /* t.tms_stime / HZ */,
4609 (double)0 /* t.tms_cutime / HZ */,
4610 (double)0 /* t.tms_cstime / HZ */,
4611 (double)system_uptime() / 1000);
4612}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004613#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004615posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004616{
4617 struct tms t;
4618 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004619 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004620 return NULL;
4621 errno = 0;
4622 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004623 if (c == (clock_t) -1)
4624 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004625 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004626 (double)t.tms_utime / HZ,
4627 (double)t.tms_stime / HZ,
4628 (double)t.tms_cutime / HZ,
4629 (double)t.tms_cstime / HZ,
4630 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004631}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004632#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004633#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004634
4635
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004636#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004637#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004639posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004640{
4641 FILETIME create, exit, kernel, user;
4642 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004643 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004644 return NULL;
4645 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004646 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4647 /* The fields of a FILETIME structure are the hi and lo part
4648 of a 64-bit value expressed in 100 nanosecond units.
4649 1e7 is one second in such units; 1e-7 the inverse.
4650 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4651 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004652 return Py_BuildValue(
4653 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004654 (double)(kernel.dwHighDateTime*429.4967296 +
4655 kernel.dwLowDateTime*1e-7),
4656 (double)(user.dwHighDateTime*429.4967296 +
4657 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004658 (double)0,
4659 (double)0,
4660 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004661}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004662#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004663
4664#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004665PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004666"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004667Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004668#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004670
Guido van Rossumb6775db1994-08-01 11:34:53 +00004671#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004672PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004673"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004674Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004675
Barry Warsaw53699e91996-12-10 23:23:01 +00004676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004677posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004678{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004679 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004680 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004681 if (setsid() < 0)
4682 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004683 Py_INCREF(Py_None);
4684 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004685}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004686#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004687
Guido van Rossumb6775db1994-08-01 11:34:53 +00004688#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004689PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004690"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004691Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004692
Barry Warsaw53699e91996-12-10 23:23:01 +00004693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004694posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004695{
4696 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004697 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004698 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004699 if (setpgid(pid, pgrp) < 0)
4700 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004701 Py_INCREF(Py_None);
4702 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004703}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004704#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004705
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004706
Guido van Rossumb6775db1994-08-01 11:34:53 +00004707#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004708PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004709"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004710Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004711
Barry Warsaw53699e91996-12-10 23:23:01 +00004712static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004713posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004714{
4715 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004716 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004717 return NULL;
4718 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004719 if (pgid < 0)
4720 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004721 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004722}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004723#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004724
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004725
Guido van Rossumb6775db1994-08-01 11:34:53 +00004726#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004727PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004728"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004729Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004730
Barry Warsaw53699e91996-12-10 23:23:01 +00004731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004732posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004733{
4734 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004735 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004736 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004737 if (tcsetpgrp(fd, pgid) < 0)
4738 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004739 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004740 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004741}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004742#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004743
Guido van Rossum687dd131993-05-17 08:34:16 +00004744/* Functions acting on file descriptors */
4745
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004746PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004747"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004748Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004749
Barry Warsaw53699e91996-12-10 23:23:01 +00004750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004751posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004752{
Mark Hammondef8b6542001-05-13 08:04:26 +00004753 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004754 int flag;
4755 int mode = 0777;
4756 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004757
4758#ifdef MS_WINDOWS
4759 if (unicode_file_names()) {
4760 PyUnicodeObject *po;
4761 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4762 Py_BEGIN_ALLOW_THREADS
4763 /* PyUnicode_AS_UNICODE OK without thread
4764 lock as it is a simple dereference. */
4765 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4766 Py_END_ALLOW_THREADS
4767 if (fd < 0)
4768 return posix_error();
4769 return PyInt_FromLong((long)fd);
4770 }
4771 /* Drop the argument parsing error as narrow strings
4772 are also valid. */
4773 PyErr_Clear();
4774 }
4775#endif
4776
Tim Peters5aa91602002-01-30 05:46:57 +00004777 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004778 Py_FileSystemDefaultEncoding, &file,
4779 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004780 return NULL;
4781
Barry Warsaw53699e91996-12-10 23:23:01 +00004782 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004783 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004784 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004785 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004786 return posix_error_with_allocated_filename(file);
4787 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004788 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004789}
4790
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004791
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004792PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004793"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004794Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004795
Barry Warsaw53699e91996-12-10 23:23:01 +00004796static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004797posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004798{
4799 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004800 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004801 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004802 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004803 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004804 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004805 if (res < 0)
4806 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004807 Py_INCREF(Py_None);
4808 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004809}
4810
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004811
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004812PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004813"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004814Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004815
Barry Warsaw53699e91996-12-10 23:23:01 +00004816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004817posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004818{
4819 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004820 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004821 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004822 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004823 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004824 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004825 if (fd < 0)
4826 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004827 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004828}
4829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004830
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004831PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004832"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004833Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004834
Barry Warsaw53699e91996-12-10 23:23:01 +00004835static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004836posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004837{
4838 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004839 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004840 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004841 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004842 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004843 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004844 if (res < 0)
4845 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004846 Py_INCREF(Py_None);
4847 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004848}
4849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004850
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004851PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004852"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004853Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004854
Barry Warsaw53699e91996-12-10 23:23:01 +00004855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004856posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004857{
4858 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004859#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004860 LONG_LONG pos, res;
4861#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004862 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004863#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004864 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004865 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004866 return NULL;
4867#ifdef SEEK_SET
4868 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4869 switch (how) {
4870 case 0: how = SEEK_SET; break;
4871 case 1: how = SEEK_CUR; break;
4872 case 2: how = SEEK_END; break;
4873 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004874#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004875
4876#if !defined(HAVE_LARGEFILE_SUPPORT)
4877 pos = PyInt_AsLong(posobj);
4878#else
4879 pos = PyLong_Check(posobj) ?
4880 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4881#endif
4882 if (PyErr_Occurred())
4883 return NULL;
4884
Barry Warsaw53699e91996-12-10 23:23:01 +00004885 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004886#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004887 res = _lseeki64(fd, pos, how);
4888#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004889 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004890#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004891 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004892 if (res < 0)
4893 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004894
4895#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004896 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004897#else
4898 return PyLong_FromLongLong(res);
4899#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004900}
4901
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004902
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004903PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004904"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004905Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004906
Barry Warsaw53699e91996-12-10 23:23:01 +00004907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004908posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004909{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004910 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004911 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004912 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004913 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004914 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004915 if (buffer == NULL)
4916 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004917 Py_BEGIN_ALLOW_THREADS
4918 n = read(fd, PyString_AsString(buffer), size);
4919 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004920 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004921 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004922 return posix_error();
4923 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004924 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004925 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004926 return buffer;
4927}
4928
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004929
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004930PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004931"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004932Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004933
Barry Warsaw53699e91996-12-10 23:23:01 +00004934static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004935posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004936{
4937 int fd, size;
4938 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004939 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004940 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004941 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004942 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004943 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004944 if (size < 0)
4945 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004946 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004947}
4948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004949
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004950PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004951"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004952Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004953
Barry Warsaw53699e91996-12-10 23:23:01 +00004954static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004955posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004956{
4957 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004958 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004959 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004960 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004961 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004962 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004963 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004964 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004965 if (res != 0)
4966 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004967
Fred Drake699f3522000-06-29 21:12:41 +00004968 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004969}
4970
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004971
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004972PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004973"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004974Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004975
Barry Warsaw53699e91996-12-10 23:23:01 +00004976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004977posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004978{
Guido van Rossum687dd131993-05-17 08:34:16 +00004979 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004980 char *mode = "r";
4981 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004982 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004983 PyObject *f;
4984 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004985 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004986
Barry Warsaw53699e91996-12-10 23:23:01 +00004987 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004988 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004989 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004990 if (fp == NULL)
4991 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00004992 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004993 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004994 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004995 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004996}
4997
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004998PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004999"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005000Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005001connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005002
5003static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005004posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005005{
5006 int fd;
5007 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5008 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005009 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005010}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005011
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005012#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005013PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005014"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005015Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005016
Barry Warsaw53699e91996-12-10 23:23:01 +00005017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005018posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005019{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005020#if defined(PYOS_OS2)
5021 HFILE read, write;
5022 APIRET rc;
5023
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005024 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005025 return NULL;
5026
5027 Py_BEGIN_ALLOW_THREADS
5028 rc = DosCreatePipe( &read, &write, 4096);
5029 Py_END_ALLOW_THREADS
5030 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005031 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005032
5033 return Py_BuildValue("(ii)", read, write);
5034#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005035#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005036 int fds[2];
5037 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005038 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00005039 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005040 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005041 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005042 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005043 if (res != 0)
5044 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005045 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005046#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005047 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005048 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005049 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005050 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00005051 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005052 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005053 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005054 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005055 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005056 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005057 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5058 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005059 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005060#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005061#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005062}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005063#endif /* HAVE_PIPE */
5064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005065
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005066#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005067PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005068"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005069Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005070
Barry Warsaw53699e91996-12-10 23:23:01 +00005071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005072posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005073{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005074 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005075 int mode = 0666;
5076 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005077 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005078 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005079 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005080 res = mkfifo(filename, mode);
5081 Py_END_ALLOW_THREADS
5082 if (res < 0)
5083 return posix_error();
5084 Py_INCREF(Py_None);
5085 return Py_None;
5086}
5087#endif
5088
5089
Neal Norwitz11690112002-07-30 01:08:28 +00005090#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005091PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005092"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005093Create a filesystem node (file, device special file or named pipe)\n\
5094named filename. mode specifies both the permissions to use and the\n\
5095type of node to be created, being combined (bitwise OR) with one of\n\
5096S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005097device defines the newly created device special file (probably using\n\
5098os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005099
5100
5101static PyObject *
5102posix_mknod(PyObject *self, PyObject *args)
5103{
5104 char *filename;
5105 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005106 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005107 int res;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005108 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005109 return NULL;
5110 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005111 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005112 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005113 if (res < 0)
5114 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005115 Py_INCREF(Py_None);
5116 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005117}
5118#endif
5119
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005120#ifdef HAVE_DEVICE_MACROS
5121PyDoc_STRVAR(posix_major__doc__,
5122"major(device) -> major number\n\
5123Extracts a device major number from a raw device number.");
5124
5125static PyObject *
5126posix_major(PyObject *self, PyObject *args)
5127{
5128 int device;
5129 if (!PyArg_ParseTuple(args, "i:major", &device))
5130 return NULL;
5131 return PyInt_FromLong((long)major(device));
5132}
5133
5134PyDoc_STRVAR(posix_minor__doc__,
5135"minor(device) -> minor number\n\
5136Extracts a device minor number from a raw device number.");
5137
5138static PyObject *
5139posix_minor(PyObject *self, PyObject *args)
5140{
5141 int device;
5142 if (!PyArg_ParseTuple(args, "i:minor", &device))
5143 return NULL;
5144 return PyInt_FromLong((long)minor(device));
5145}
5146
5147PyDoc_STRVAR(posix_makedev__doc__,
5148"makedev(major, minor) -> device number\n\
5149Composes a raw device number from the major and minor device numbers.");
5150
5151static PyObject *
5152posix_makedev(PyObject *self, PyObject *args)
5153{
5154 int major, minor;
5155 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5156 return NULL;
5157 return PyInt_FromLong((long)makedev(major, minor));
5158}
5159#endif /* device macros */
5160
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005161
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005162#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005163PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005164"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005165Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005166
Barry Warsaw53699e91996-12-10 23:23:01 +00005167static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005168posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005169{
5170 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005171 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005172 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005173 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005174
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005175 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005176 return NULL;
5177
5178#if !defined(HAVE_LARGEFILE_SUPPORT)
5179 length = PyInt_AsLong(lenobj);
5180#else
5181 length = PyLong_Check(lenobj) ?
5182 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5183#endif
5184 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005185 return NULL;
5186
Barry Warsaw53699e91996-12-10 23:23:01 +00005187 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005188 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005189 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005190 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005191 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005192 return NULL;
5193 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005194 Py_INCREF(Py_None);
5195 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005196}
5197#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005198
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005199#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005200PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005201"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005202Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005203
Fred Drake762e2061999-08-26 17:23:54 +00005204/* Save putenv() parameters as values here, so we can collect them when they
5205 * get re-set with another call for the same key. */
5206static PyObject *posix_putenv_garbage;
5207
Tim Peters5aa91602002-01-30 05:46:57 +00005208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005209posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005210{
5211 char *s1, *s2;
5212 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005213 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005214 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005215
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005216 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005217 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005218
5219#if defined(PYOS_OS2)
5220 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5221 APIRET rc;
5222
5223 if (strlen(s2) == 0) /* If New Value is an Empty String */
5224 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5225
5226 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5227 if (rc != NO_ERROR)
5228 return os2_error(rc);
5229
5230 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5231 APIRET rc;
5232
5233 if (strlen(s2) == 0) /* If New Value is an Empty String */
5234 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5235
5236 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5237 if (rc != NO_ERROR)
5238 return os2_error(rc);
5239 } else {
5240#endif
5241
Fred Drake762e2061999-08-26 17:23:54 +00005242 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005243 len = strlen(s1) + strlen(s2) + 2;
5244 /* len includes space for a trailing \0; the size arg to
5245 PyString_FromStringAndSize does not count that */
5246 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005247 if (newstr == NULL)
5248 return PyErr_NoMemory();
5249 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005250 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005251 if (putenv(new)) {
5252 posix_error();
5253 return NULL;
5254 }
Fred Drake762e2061999-08-26 17:23:54 +00005255 /* Install the first arg and newstr in posix_putenv_garbage;
5256 * this will cause previous value to be collected. This has to
5257 * happen after the real putenv() call because the old value
5258 * was still accessible until then. */
5259 if (PyDict_SetItem(posix_putenv_garbage,
5260 PyTuple_GET_ITEM(args, 0), newstr)) {
5261 /* really not much we can do; just leak */
5262 PyErr_Clear();
5263 }
5264 else {
5265 Py_DECREF(newstr);
5266 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005267
5268#if defined(PYOS_OS2)
5269 }
5270#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005271 Py_INCREF(Py_None);
5272 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005273}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005274#endif /* putenv */
5275
Guido van Rossumc524d952001-10-19 01:31:59 +00005276#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005277PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005278"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005279Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005280
5281static PyObject *
5282posix_unsetenv(PyObject *self, PyObject *args)
5283{
5284 char *s1;
5285
5286 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5287 return NULL;
5288
5289 unsetenv(s1);
5290
5291 /* Remove the key from posix_putenv_garbage;
5292 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005293 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005294 * old value was still accessible until then.
5295 */
5296 if (PyDict_DelItem(posix_putenv_garbage,
5297 PyTuple_GET_ITEM(args, 0))) {
5298 /* really not much we can do; just leak */
5299 PyErr_Clear();
5300 }
5301
5302 Py_INCREF(Py_None);
5303 return Py_None;
5304}
5305#endif /* unsetenv */
5306
Guido van Rossumb6a47161997-09-15 22:54:34 +00005307#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005308PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005309"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005310Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005311
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005313posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005314{
5315 int code;
5316 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005317 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005318 return NULL;
5319 message = strerror(code);
5320 if (message == NULL) {
5321 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005322 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005323 return NULL;
5324 }
5325 return PyString_FromString(message);
5326}
5327#endif /* strerror */
5328
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005329
Guido van Rossumc9641791998-08-04 15:26:23 +00005330#ifdef HAVE_SYS_WAIT_H
5331
Fred Drake106c1a02002-04-23 15:58:02 +00005332#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005333PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005334"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005335Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005336
5337static PyObject *
5338posix_WCOREDUMP(PyObject *self, PyObject *args)
5339{
5340#ifdef UNION_WAIT
5341 union wait status;
5342#define status_i (status.w_status)
5343#else
5344 int status;
5345#define status_i status
5346#endif
5347 status_i = 0;
5348
5349 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5350 {
5351 return NULL;
5352 }
5353
5354 return PyBool_FromLong(WCOREDUMP(status));
5355#undef status_i
5356}
5357#endif /* WCOREDUMP */
5358
5359#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005360PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005361"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005362Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005363job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005364
5365static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005366posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005367{
5368#ifdef UNION_WAIT
5369 union wait status;
5370#define status_i (status.w_status)
5371#else
5372 int status;
5373#define status_i status
5374#endif
5375 status_i = 0;
5376
5377 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5378 {
5379 return NULL;
5380 }
5381
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005382 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005383#undef status_i
5384}
5385#endif /* WIFCONTINUED */
5386
Guido van Rossumc9641791998-08-04 15:26:23 +00005387#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005388PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005389"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005390Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005391
5392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005393posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005394{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005395#ifdef UNION_WAIT
5396 union wait status;
5397#define status_i (status.w_status)
5398#else
5399 int status;
5400#define status_i status
5401#endif
5402 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005403
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005404 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005405 {
5406 return NULL;
5407 }
Tim Peters5aa91602002-01-30 05:46:57 +00005408
Fred Drake106c1a02002-04-23 15:58:02 +00005409 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005410#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005411}
5412#endif /* WIFSTOPPED */
5413
5414#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005415PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005416"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005417Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005418
5419static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005420posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005421{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005422#ifdef UNION_WAIT
5423 union wait status;
5424#define status_i (status.w_status)
5425#else
5426 int status;
5427#define status_i status
5428#endif
5429 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005430
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005431 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005432 {
5433 return NULL;
5434 }
Tim Peters5aa91602002-01-30 05:46:57 +00005435
Fred Drake106c1a02002-04-23 15:58:02 +00005436 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005437#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005438}
5439#endif /* WIFSIGNALED */
5440
5441#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005442PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005443"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005444Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005445system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005446
5447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005448posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005449{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005450#ifdef UNION_WAIT
5451 union wait status;
5452#define status_i (status.w_status)
5453#else
5454 int status;
5455#define status_i status
5456#endif
5457 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005458
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005459 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005460 {
5461 return NULL;
5462 }
Tim Peters5aa91602002-01-30 05:46:57 +00005463
Fred Drake106c1a02002-04-23 15:58:02 +00005464 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005465#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005466}
5467#endif /* WIFEXITED */
5468
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005469#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005470PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005471"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005472Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005473
5474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005475posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005476{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005477#ifdef UNION_WAIT
5478 union wait status;
5479#define status_i (status.w_status)
5480#else
5481 int status;
5482#define status_i status
5483#endif
5484 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005485
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005486 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005487 {
5488 return NULL;
5489 }
Tim Peters5aa91602002-01-30 05:46:57 +00005490
Guido van Rossumc9641791998-08-04 15:26:23 +00005491 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005492#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005493}
5494#endif /* WEXITSTATUS */
5495
5496#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005498"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005499Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005500value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005501
5502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005503posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005504{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005505#ifdef UNION_WAIT
5506 union wait status;
5507#define status_i (status.w_status)
5508#else
5509 int status;
5510#define status_i status
5511#endif
5512 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005513
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005514 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005515 {
5516 return NULL;
5517 }
Tim Peters5aa91602002-01-30 05:46:57 +00005518
Guido van Rossumc9641791998-08-04 15:26:23 +00005519 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005520#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005521}
5522#endif /* WTERMSIG */
5523
5524#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005525PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005526"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005527Return the signal that stopped the process that provided\n\
5528the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005529
5530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005531posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005532{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005533#ifdef UNION_WAIT
5534 union wait status;
5535#define status_i (status.w_status)
5536#else
5537 int status;
5538#define status_i status
5539#endif
5540 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005541
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005542 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005543 {
5544 return NULL;
5545 }
Tim Peters5aa91602002-01-30 05:46:57 +00005546
Guido van Rossumc9641791998-08-04 15:26:23 +00005547 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005548#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005549}
5550#endif /* WSTOPSIG */
5551
5552#endif /* HAVE_SYS_WAIT_H */
5553
5554
Guido van Rossum94f6f721999-01-06 18:42:14 +00005555#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005556#ifdef _SCO_DS
5557/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5558 needed definitions in sys/statvfs.h */
5559#define _SVID3
5560#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005561#include <sys/statvfs.h>
5562
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005563static PyObject*
5564_pystatvfs_fromstructstatvfs(struct statvfs st) {
5565 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5566 if (v == NULL)
5567 return NULL;
5568
5569#if !defined(HAVE_LARGEFILE_SUPPORT)
5570 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5571 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5572 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5573 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5574 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5575 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5576 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5577 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5578 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5579 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5580#else
5581 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5582 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005583 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005584 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005585 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005586 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5587 PyStructSequence_SET_ITEM(v, 4,
5588 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005589 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005590 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005591 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005592 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005593 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005594 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5595 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5596 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5597#endif
5598
5599 return v;
5600}
5601
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005603"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005604Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005605
5606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005607posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005608{
5609 int fd, res;
5610 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005611
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005612 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005613 return NULL;
5614 Py_BEGIN_ALLOW_THREADS
5615 res = fstatvfs(fd, &st);
5616 Py_END_ALLOW_THREADS
5617 if (res != 0)
5618 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005619
5620 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005621}
5622#endif /* HAVE_FSTATVFS */
5623
5624
5625#if defined(HAVE_STATVFS)
5626#include <sys/statvfs.h>
5627
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005628PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005629"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005630Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005631
5632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005633posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005634{
5635 char *path;
5636 int res;
5637 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005638 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005639 return NULL;
5640 Py_BEGIN_ALLOW_THREADS
5641 res = statvfs(path, &st);
5642 Py_END_ALLOW_THREADS
5643 if (res != 0)
5644 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005645
5646 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005647}
5648#endif /* HAVE_STATVFS */
5649
5650
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005651#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005652PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005653"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005654Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005655The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005656or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005657
5658static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005659posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005660{
5661 PyObject *result = NULL;
5662 char *dir = NULL;
5663 char *pfx = NULL;
5664 char *name;
5665
5666 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5667 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005668
5669 if (PyErr_Warn(PyExc_RuntimeWarning,
5670 "tempnam is a potential security risk to your program") < 0)
5671 return NULL;
5672
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005673#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005674 name = _tempnam(dir, pfx);
5675#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005676 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005677#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005678 if (name == NULL)
5679 return PyErr_NoMemory();
5680 result = PyString_FromString(name);
5681 free(name);
5682 return result;
5683}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005684#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005685
5686
5687#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005689"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005691
5692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005693posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005694{
5695 FILE *fp;
5696
5697 if (!PyArg_ParseTuple(args, ":tmpfile"))
5698 return NULL;
5699 fp = tmpfile();
5700 if (fp == NULL)
5701 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005702 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005703}
5704#endif
5705
5706
5707#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005708PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005709"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005710Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005711
5712static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005713posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005714{
5715 char buffer[L_tmpnam];
5716 char *name;
5717
5718 if (!PyArg_ParseTuple(args, ":tmpnam"))
5719 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005720
5721 if (PyErr_Warn(PyExc_RuntimeWarning,
5722 "tmpnam is a potential security risk to your program") < 0)
5723 return NULL;
5724
Greg Wardb48bc172000-03-01 21:51:56 +00005725#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005726 name = tmpnam_r(buffer);
5727#else
5728 name = tmpnam(buffer);
5729#endif
5730 if (name == NULL) {
5731 PyErr_SetObject(PyExc_OSError,
5732 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005733#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005734 "unexpected NULL from tmpnam_r"
5735#else
5736 "unexpected NULL from tmpnam"
5737#endif
5738 ));
5739 return NULL;
5740 }
5741 return PyString_FromString(buffer);
5742}
5743#endif
5744
5745
Fred Drakec9680921999-12-13 16:37:25 +00005746/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5747 * It maps strings representing configuration variable names to
5748 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005749 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005750 * rarely-used constants. There are three separate tables that use
5751 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005752 *
5753 * This code is always included, even if none of the interfaces that
5754 * need it are included. The #if hackery needed to avoid it would be
5755 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005756 */
5757struct constdef {
5758 char *name;
5759 long value;
5760};
5761
Fred Drake12c6e2d1999-12-14 21:25:03 +00005762static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005763conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5764 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005765{
5766 if (PyInt_Check(arg)) {
5767 *valuep = PyInt_AS_LONG(arg);
5768 return 1;
5769 }
5770 if (PyString_Check(arg)) {
5771 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005772 size_t lo = 0;
5773 size_t mid;
5774 size_t hi = tablesize;
5775 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005776 char *confname = PyString_AS_STRING(arg);
5777 while (lo < hi) {
5778 mid = (lo + hi) / 2;
5779 cmp = strcmp(confname, table[mid].name);
5780 if (cmp < 0)
5781 hi = mid;
5782 else if (cmp > 0)
5783 lo = mid + 1;
5784 else {
5785 *valuep = table[mid].value;
5786 return 1;
5787 }
5788 }
5789 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5790 }
5791 else
5792 PyErr_SetString(PyExc_TypeError,
5793 "configuration names must be strings or integers");
5794 return 0;
5795}
5796
5797
5798#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5799static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005800#ifdef _PC_ABI_AIO_XFER_MAX
5801 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5802#endif
5803#ifdef _PC_ABI_ASYNC_IO
5804 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5805#endif
Fred Drakec9680921999-12-13 16:37:25 +00005806#ifdef _PC_ASYNC_IO
5807 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5808#endif
5809#ifdef _PC_CHOWN_RESTRICTED
5810 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5811#endif
5812#ifdef _PC_FILESIZEBITS
5813 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5814#endif
5815#ifdef _PC_LAST
5816 {"PC_LAST", _PC_LAST},
5817#endif
5818#ifdef _PC_LINK_MAX
5819 {"PC_LINK_MAX", _PC_LINK_MAX},
5820#endif
5821#ifdef _PC_MAX_CANON
5822 {"PC_MAX_CANON", _PC_MAX_CANON},
5823#endif
5824#ifdef _PC_MAX_INPUT
5825 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5826#endif
5827#ifdef _PC_NAME_MAX
5828 {"PC_NAME_MAX", _PC_NAME_MAX},
5829#endif
5830#ifdef _PC_NO_TRUNC
5831 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5832#endif
5833#ifdef _PC_PATH_MAX
5834 {"PC_PATH_MAX", _PC_PATH_MAX},
5835#endif
5836#ifdef _PC_PIPE_BUF
5837 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5838#endif
5839#ifdef _PC_PRIO_IO
5840 {"PC_PRIO_IO", _PC_PRIO_IO},
5841#endif
5842#ifdef _PC_SOCK_MAXBUF
5843 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5844#endif
5845#ifdef _PC_SYNC_IO
5846 {"PC_SYNC_IO", _PC_SYNC_IO},
5847#endif
5848#ifdef _PC_VDISABLE
5849 {"PC_VDISABLE", _PC_VDISABLE},
5850#endif
5851};
5852
Fred Drakec9680921999-12-13 16:37:25 +00005853static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005854conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005855{
5856 return conv_confname(arg, valuep, posix_constants_pathconf,
5857 sizeof(posix_constants_pathconf)
5858 / sizeof(struct constdef));
5859}
5860#endif
5861
5862#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005863PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005864"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005865Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005866If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005867
5868static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005869posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005870{
5871 PyObject *result = NULL;
5872 int name, fd;
5873
Fred Drake12c6e2d1999-12-14 21:25:03 +00005874 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5875 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005876 long limit;
5877
5878 errno = 0;
5879 limit = fpathconf(fd, name);
5880 if (limit == -1 && errno != 0)
5881 posix_error();
5882 else
5883 result = PyInt_FromLong(limit);
5884 }
5885 return result;
5886}
5887#endif
5888
5889
5890#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005891PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005892"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005893Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005894If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005895
5896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005897posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005898{
5899 PyObject *result = NULL;
5900 int name;
5901 char *path;
5902
5903 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5904 conv_path_confname, &name)) {
5905 long limit;
5906
5907 errno = 0;
5908 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005909 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005910 if (errno == EINVAL)
5911 /* could be a path or name problem */
5912 posix_error();
5913 else
5914 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005915 }
Fred Drakec9680921999-12-13 16:37:25 +00005916 else
5917 result = PyInt_FromLong(limit);
5918 }
5919 return result;
5920}
5921#endif
5922
5923#ifdef HAVE_CONFSTR
5924static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005925#ifdef _CS_ARCHITECTURE
5926 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5927#endif
5928#ifdef _CS_HOSTNAME
5929 {"CS_HOSTNAME", _CS_HOSTNAME},
5930#endif
5931#ifdef _CS_HW_PROVIDER
5932 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5933#endif
5934#ifdef _CS_HW_SERIAL
5935 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5936#endif
5937#ifdef _CS_INITTAB_NAME
5938 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5939#endif
Fred Drakec9680921999-12-13 16:37:25 +00005940#ifdef _CS_LFS64_CFLAGS
5941 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5942#endif
5943#ifdef _CS_LFS64_LDFLAGS
5944 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5945#endif
5946#ifdef _CS_LFS64_LIBS
5947 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5948#endif
5949#ifdef _CS_LFS64_LINTFLAGS
5950 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5951#endif
5952#ifdef _CS_LFS_CFLAGS
5953 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5954#endif
5955#ifdef _CS_LFS_LDFLAGS
5956 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5957#endif
5958#ifdef _CS_LFS_LIBS
5959 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5960#endif
5961#ifdef _CS_LFS_LINTFLAGS
5962 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5963#endif
Fred Draked86ed291999-12-15 15:34:33 +00005964#ifdef _CS_MACHINE
5965 {"CS_MACHINE", _CS_MACHINE},
5966#endif
Fred Drakec9680921999-12-13 16:37:25 +00005967#ifdef _CS_PATH
5968 {"CS_PATH", _CS_PATH},
5969#endif
Fred Draked86ed291999-12-15 15:34:33 +00005970#ifdef _CS_RELEASE
5971 {"CS_RELEASE", _CS_RELEASE},
5972#endif
5973#ifdef _CS_SRPC_DOMAIN
5974 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5975#endif
5976#ifdef _CS_SYSNAME
5977 {"CS_SYSNAME", _CS_SYSNAME},
5978#endif
5979#ifdef _CS_VERSION
5980 {"CS_VERSION", _CS_VERSION},
5981#endif
Fred Drakec9680921999-12-13 16:37:25 +00005982#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5983 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5984#endif
5985#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5986 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5987#endif
5988#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5989 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5990#endif
5991#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5992 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5993#endif
5994#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5995 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5996#endif
5997#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5998 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5999#endif
6000#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6001 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6002#endif
6003#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6004 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6005#endif
6006#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6007 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6008#endif
6009#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6010 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6011#endif
6012#ifdef _CS_XBS5_LP64_OFF64_LIBS
6013 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6014#endif
6015#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6016 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6017#endif
6018#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6019 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6020#endif
6021#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6022 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6023#endif
6024#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6025 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6026#endif
6027#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6028 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6029#endif
Fred Draked86ed291999-12-15 15:34:33 +00006030#ifdef _MIPS_CS_AVAIL_PROCESSORS
6031 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6032#endif
6033#ifdef _MIPS_CS_BASE
6034 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6035#endif
6036#ifdef _MIPS_CS_HOSTID
6037 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6038#endif
6039#ifdef _MIPS_CS_HW_NAME
6040 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6041#endif
6042#ifdef _MIPS_CS_NUM_PROCESSORS
6043 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6044#endif
6045#ifdef _MIPS_CS_OSREL_MAJ
6046 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6047#endif
6048#ifdef _MIPS_CS_OSREL_MIN
6049 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6050#endif
6051#ifdef _MIPS_CS_OSREL_PATCH
6052 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6053#endif
6054#ifdef _MIPS_CS_OS_NAME
6055 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6056#endif
6057#ifdef _MIPS_CS_OS_PROVIDER
6058 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6059#endif
6060#ifdef _MIPS_CS_PROCESSORS
6061 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6062#endif
6063#ifdef _MIPS_CS_SERIAL
6064 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6065#endif
6066#ifdef _MIPS_CS_VENDOR
6067 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6068#endif
Fred Drakec9680921999-12-13 16:37:25 +00006069};
6070
6071static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006072conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006073{
6074 return conv_confname(arg, valuep, posix_constants_confstr,
6075 sizeof(posix_constants_confstr)
6076 / sizeof(struct constdef));
6077}
6078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006082
6083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006084posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006085{
6086 PyObject *result = NULL;
6087 int name;
6088 char buffer[64];
6089
6090 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6091 int len = confstr(name, buffer, sizeof(buffer));
6092
Fred Drakec9680921999-12-13 16:37:25 +00006093 errno = 0;
6094 if (len == 0) {
6095 if (errno != 0)
6096 posix_error();
6097 else
6098 result = PyString_FromString("");
6099 }
6100 else {
6101 if (len >= sizeof(buffer)) {
6102 result = PyString_FromStringAndSize(NULL, len);
6103 if (result != NULL)
6104 confstr(name, PyString_AS_STRING(result), len+1);
6105 }
6106 else
6107 result = PyString_FromString(buffer);
6108 }
6109 }
6110 return result;
6111}
6112#endif
6113
6114
6115#ifdef HAVE_SYSCONF
6116static struct constdef posix_constants_sysconf[] = {
6117#ifdef _SC_2_CHAR_TERM
6118 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6119#endif
6120#ifdef _SC_2_C_BIND
6121 {"SC_2_C_BIND", _SC_2_C_BIND},
6122#endif
6123#ifdef _SC_2_C_DEV
6124 {"SC_2_C_DEV", _SC_2_C_DEV},
6125#endif
6126#ifdef _SC_2_C_VERSION
6127 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6128#endif
6129#ifdef _SC_2_FORT_DEV
6130 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6131#endif
6132#ifdef _SC_2_FORT_RUN
6133 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6134#endif
6135#ifdef _SC_2_LOCALEDEF
6136 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6137#endif
6138#ifdef _SC_2_SW_DEV
6139 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6140#endif
6141#ifdef _SC_2_UPE
6142 {"SC_2_UPE", _SC_2_UPE},
6143#endif
6144#ifdef _SC_2_VERSION
6145 {"SC_2_VERSION", _SC_2_VERSION},
6146#endif
Fred Draked86ed291999-12-15 15:34:33 +00006147#ifdef _SC_ABI_ASYNCHRONOUS_IO
6148 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6149#endif
6150#ifdef _SC_ACL
6151 {"SC_ACL", _SC_ACL},
6152#endif
Fred Drakec9680921999-12-13 16:37:25 +00006153#ifdef _SC_AIO_LISTIO_MAX
6154 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6155#endif
Fred Drakec9680921999-12-13 16:37:25 +00006156#ifdef _SC_AIO_MAX
6157 {"SC_AIO_MAX", _SC_AIO_MAX},
6158#endif
6159#ifdef _SC_AIO_PRIO_DELTA_MAX
6160 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6161#endif
6162#ifdef _SC_ARG_MAX
6163 {"SC_ARG_MAX", _SC_ARG_MAX},
6164#endif
6165#ifdef _SC_ASYNCHRONOUS_IO
6166 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6167#endif
6168#ifdef _SC_ATEXIT_MAX
6169 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6170#endif
Fred Draked86ed291999-12-15 15:34:33 +00006171#ifdef _SC_AUDIT
6172 {"SC_AUDIT", _SC_AUDIT},
6173#endif
Fred Drakec9680921999-12-13 16:37:25 +00006174#ifdef _SC_AVPHYS_PAGES
6175 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6176#endif
6177#ifdef _SC_BC_BASE_MAX
6178 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6179#endif
6180#ifdef _SC_BC_DIM_MAX
6181 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6182#endif
6183#ifdef _SC_BC_SCALE_MAX
6184 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6185#endif
6186#ifdef _SC_BC_STRING_MAX
6187 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6188#endif
Fred Draked86ed291999-12-15 15:34:33 +00006189#ifdef _SC_CAP
6190 {"SC_CAP", _SC_CAP},
6191#endif
Fred Drakec9680921999-12-13 16:37:25 +00006192#ifdef _SC_CHARCLASS_NAME_MAX
6193 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6194#endif
6195#ifdef _SC_CHAR_BIT
6196 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6197#endif
6198#ifdef _SC_CHAR_MAX
6199 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6200#endif
6201#ifdef _SC_CHAR_MIN
6202 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6203#endif
6204#ifdef _SC_CHILD_MAX
6205 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6206#endif
6207#ifdef _SC_CLK_TCK
6208 {"SC_CLK_TCK", _SC_CLK_TCK},
6209#endif
6210#ifdef _SC_COHER_BLKSZ
6211 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6212#endif
6213#ifdef _SC_COLL_WEIGHTS_MAX
6214 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6215#endif
6216#ifdef _SC_DCACHE_ASSOC
6217 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6218#endif
6219#ifdef _SC_DCACHE_BLKSZ
6220 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6221#endif
6222#ifdef _SC_DCACHE_LINESZ
6223 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6224#endif
6225#ifdef _SC_DCACHE_SZ
6226 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6227#endif
6228#ifdef _SC_DCACHE_TBLKSZ
6229 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6230#endif
6231#ifdef _SC_DELAYTIMER_MAX
6232 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6233#endif
6234#ifdef _SC_EQUIV_CLASS_MAX
6235 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6236#endif
6237#ifdef _SC_EXPR_NEST_MAX
6238 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6239#endif
6240#ifdef _SC_FSYNC
6241 {"SC_FSYNC", _SC_FSYNC},
6242#endif
6243#ifdef _SC_GETGR_R_SIZE_MAX
6244 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6245#endif
6246#ifdef _SC_GETPW_R_SIZE_MAX
6247 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6248#endif
6249#ifdef _SC_ICACHE_ASSOC
6250 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6251#endif
6252#ifdef _SC_ICACHE_BLKSZ
6253 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6254#endif
6255#ifdef _SC_ICACHE_LINESZ
6256 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6257#endif
6258#ifdef _SC_ICACHE_SZ
6259 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6260#endif
Fred Draked86ed291999-12-15 15:34:33 +00006261#ifdef _SC_INF
6262 {"SC_INF", _SC_INF},
6263#endif
Fred Drakec9680921999-12-13 16:37:25 +00006264#ifdef _SC_INT_MAX
6265 {"SC_INT_MAX", _SC_INT_MAX},
6266#endif
6267#ifdef _SC_INT_MIN
6268 {"SC_INT_MIN", _SC_INT_MIN},
6269#endif
6270#ifdef _SC_IOV_MAX
6271 {"SC_IOV_MAX", _SC_IOV_MAX},
6272#endif
Fred Draked86ed291999-12-15 15:34:33 +00006273#ifdef _SC_IP_SECOPTS
6274 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6275#endif
Fred Drakec9680921999-12-13 16:37:25 +00006276#ifdef _SC_JOB_CONTROL
6277 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6278#endif
Fred Draked86ed291999-12-15 15:34:33 +00006279#ifdef _SC_KERN_POINTERS
6280 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6281#endif
6282#ifdef _SC_KERN_SIM
6283 {"SC_KERN_SIM", _SC_KERN_SIM},
6284#endif
Fred Drakec9680921999-12-13 16:37:25 +00006285#ifdef _SC_LINE_MAX
6286 {"SC_LINE_MAX", _SC_LINE_MAX},
6287#endif
6288#ifdef _SC_LOGIN_NAME_MAX
6289 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6290#endif
6291#ifdef _SC_LOGNAME_MAX
6292 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6293#endif
6294#ifdef _SC_LONG_BIT
6295 {"SC_LONG_BIT", _SC_LONG_BIT},
6296#endif
Fred Draked86ed291999-12-15 15:34:33 +00006297#ifdef _SC_MAC
6298 {"SC_MAC", _SC_MAC},
6299#endif
Fred Drakec9680921999-12-13 16:37:25 +00006300#ifdef _SC_MAPPED_FILES
6301 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6302#endif
6303#ifdef _SC_MAXPID
6304 {"SC_MAXPID", _SC_MAXPID},
6305#endif
6306#ifdef _SC_MB_LEN_MAX
6307 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6308#endif
6309#ifdef _SC_MEMLOCK
6310 {"SC_MEMLOCK", _SC_MEMLOCK},
6311#endif
6312#ifdef _SC_MEMLOCK_RANGE
6313 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6314#endif
6315#ifdef _SC_MEMORY_PROTECTION
6316 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6317#endif
6318#ifdef _SC_MESSAGE_PASSING
6319 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6320#endif
Fred Draked86ed291999-12-15 15:34:33 +00006321#ifdef _SC_MMAP_FIXED_ALIGNMENT
6322 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6323#endif
Fred Drakec9680921999-12-13 16:37:25 +00006324#ifdef _SC_MQ_OPEN_MAX
6325 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6326#endif
6327#ifdef _SC_MQ_PRIO_MAX
6328 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6329#endif
Fred Draked86ed291999-12-15 15:34:33 +00006330#ifdef _SC_NACLS_MAX
6331 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6332#endif
Fred Drakec9680921999-12-13 16:37:25 +00006333#ifdef _SC_NGROUPS_MAX
6334 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6335#endif
6336#ifdef _SC_NL_ARGMAX
6337 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6338#endif
6339#ifdef _SC_NL_LANGMAX
6340 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6341#endif
6342#ifdef _SC_NL_MSGMAX
6343 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6344#endif
6345#ifdef _SC_NL_NMAX
6346 {"SC_NL_NMAX", _SC_NL_NMAX},
6347#endif
6348#ifdef _SC_NL_SETMAX
6349 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6350#endif
6351#ifdef _SC_NL_TEXTMAX
6352 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6353#endif
6354#ifdef _SC_NPROCESSORS_CONF
6355 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6356#endif
6357#ifdef _SC_NPROCESSORS_ONLN
6358 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6359#endif
Fred Draked86ed291999-12-15 15:34:33 +00006360#ifdef _SC_NPROC_CONF
6361 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6362#endif
6363#ifdef _SC_NPROC_ONLN
6364 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6365#endif
Fred Drakec9680921999-12-13 16:37:25 +00006366#ifdef _SC_NZERO
6367 {"SC_NZERO", _SC_NZERO},
6368#endif
6369#ifdef _SC_OPEN_MAX
6370 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6371#endif
6372#ifdef _SC_PAGESIZE
6373 {"SC_PAGESIZE", _SC_PAGESIZE},
6374#endif
6375#ifdef _SC_PAGE_SIZE
6376 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6377#endif
6378#ifdef _SC_PASS_MAX
6379 {"SC_PASS_MAX", _SC_PASS_MAX},
6380#endif
6381#ifdef _SC_PHYS_PAGES
6382 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6383#endif
6384#ifdef _SC_PII
6385 {"SC_PII", _SC_PII},
6386#endif
6387#ifdef _SC_PII_INTERNET
6388 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6389#endif
6390#ifdef _SC_PII_INTERNET_DGRAM
6391 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6392#endif
6393#ifdef _SC_PII_INTERNET_STREAM
6394 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6395#endif
6396#ifdef _SC_PII_OSI
6397 {"SC_PII_OSI", _SC_PII_OSI},
6398#endif
6399#ifdef _SC_PII_OSI_CLTS
6400 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6401#endif
6402#ifdef _SC_PII_OSI_COTS
6403 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6404#endif
6405#ifdef _SC_PII_OSI_M
6406 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6407#endif
6408#ifdef _SC_PII_SOCKET
6409 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6410#endif
6411#ifdef _SC_PII_XTI
6412 {"SC_PII_XTI", _SC_PII_XTI},
6413#endif
6414#ifdef _SC_POLL
6415 {"SC_POLL", _SC_POLL},
6416#endif
6417#ifdef _SC_PRIORITIZED_IO
6418 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6419#endif
6420#ifdef _SC_PRIORITY_SCHEDULING
6421 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6422#endif
6423#ifdef _SC_REALTIME_SIGNALS
6424 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6425#endif
6426#ifdef _SC_RE_DUP_MAX
6427 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6428#endif
6429#ifdef _SC_RTSIG_MAX
6430 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6431#endif
6432#ifdef _SC_SAVED_IDS
6433 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6434#endif
6435#ifdef _SC_SCHAR_MAX
6436 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6437#endif
6438#ifdef _SC_SCHAR_MIN
6439 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6440#endif
6441#ifdef _SC_SELECT
6442 {"SC_SELECT", _SC_SELECT},
6443#endif
6444#ifdef _SC_SEMAPHORES
6445 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6446#endif
6447#ifdef _SC_SEM_NSEMS_MAX
6448 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6449#endif
6450#ifdef _SC_SEM_VALUE_MAX
6451 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6452#endif
6453#ifdef _SC_SHARED_MEMORY_OBJECTS
6454 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6455#endif
6456#ifdef _SC_SHRT_MAX
6457 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6458#endif
6459#ifdef _SC_SHRT_MIN
6460 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6461#endif
6462#ifdef _SC_SIGQUEUE_MAX
6463 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6464#endif
6465#ifdef _SC_SIGRT_MAX
6466 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6467#endif
6468#ifdef _SC_SIGRT_MIN
6469 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6470#endif
Fred Draked86ed291999-12-15 15:34:33 +00006471#ifdef _SC_SOFTPOWER
6472 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6473#endif
Fred Drakec9680921999-12-13 16:37:25 +00006474#ifdef _SC_SPLIT_CACHE
6475 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6476#endif
6477#ifdef _SC_SSIZE_MAX
6478 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6479#endif
6480#ifdef _SC_STACK_PROT
6481 {"SC_STACK_PROT", _SC_STACK_PROT},
6482#endif
6483#ifdef _SC_STREAM_MAX
6484 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6485#endif
6486#ifdef _SC_SYNCHRONIZED_IO
6487 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6488#endif
6489#ifdef _SC_THREADS
6490 {"SC_THREADS", _SC_THREADS},
6491#endif
6492#ifdef _SC_THREAD_ATTR_STACKADDR
6493 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6494#endif
6495#ifdef _SC_THREAD_ATTR_STACKSIZE
6496 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6497#endif
6498#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6499 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6500#endif
6501#ifdef _SC_THREAD_KEYS_MAX
6502 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6503#endif
6504#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6505 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6506#endif
6507#ifdef _SC_THREAD_PRIO_INHERIT
6508 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6509#endif
6510#ifdef _SC_THREAD_PRIO_PROTECT
6511 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6512#endif
6513#ifdef _SC_THREAD_PROCESS_SHARED
6514 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6515#endif
6516#ifdef _SC_THREAD_SAFE_FUNCTIONS
6517 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6518#endif
6519#ifdef _SC_THREAD_STACK_MIN
6520 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6521#endif
6522#ifdef _SC_THREAD_THREADS_MAX
6523 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6524#endif
6525#ifdef _SC_TIMERS
6526 {"SC_TIMERS", _SC_TIMERS},
6527#endif
6528#ifdef _SC_TIMER_MAX
6529 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6530#endif
6531#ifdef _SC_TTY_NAME_MAX
6532 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6533#endif
6534#ifdef _SC_TZNAME_MAX
6535 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6536#endif
6537#ifdef _SC_T_IOV_MAX
6538 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6539#endif
6540#ifdef _SC_UCHAR_MAX
6541 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6542#endif
6543#ifdef _SC_UINT_MAX
6544 {"SC_UINT_MAX", _SC_UINT_MAX},
6545#endif
6546#ifdef _SC_UIO_MAXIOV
6547 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6548#endif
6549#ifdef _SC_ULONG_MAX
6550 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6551#endif
6552#ifdef _SC_USHRT_MAX
6553 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6554#endif
6555#ifdef _SC_VERSION
6556 {"SC_VERSION", _SC_VERSION},
6557#endif
6558#ifdef _SC_WORD_BIT
6559 {"SC_WORD_BIT", _SC_WORD_BIT},
6560#endif
6561#ifdef _SC_XBS5_ILP32_OFF32
6562 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6563#endif
6564#ifdef _SC_XBS5_ILP32_OFFBIG
6565 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6566#endif
6567#ifdef _SC_XBS5_LP64_OFF64
6568 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6569#endif
6570#ifdef _SC_XBS5_LPBIG_OFFBIG
6571 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6572#endif
6573#ifdef _SC_XOPEN_CRYPT
6574 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6575#endif
6576#ifdef _SC_XOPEN_ENH_I18N
6577 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6578#endif
6579#ifdef _SC_XOPEN_LEGACY
6580 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6581#endif
6582#ifdef _SC_XOPEN_REALTIME
6583 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6584#endif
6585#ifdef _SC_XOPEN_REALTIME_THREADS
6586 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6587#endif
6588#ifdef _SC_XOPEN_SHM
6589 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6590#endif
6591#ifdef _SC_XOPEN_UNIX
6592 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6593#endif
6594#ifdef _SC_XOPEN_VERSION
6595 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6596#endif
6597#ifdef _SC_XOPEN_XCU_VERSION
6598 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6599#endif
6600#ifdef _SC_XOPEN_XPG2
6601 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6602#endif
6603#ifdef _SC_XOPEN_XPG3
6604 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6605#endif
6606#ifdef _SC_XOPEN_XPG4
6607 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6608#endif
6609};
6610
6611static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006612conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006613{
6614 return conv_confname(arg, valuep, posix_constants_sysconf,
6615 sizeof(posix_constants_sysconf)
6616 / sizeof(struct constdef));
6617}
6618
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006619PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006620"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006621Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006622
6623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006624posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006625{
6626 PyObject *result = NULL;
6627 int name;
6628
6629 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6630 int value;
6631
6632 errno = 0;
6633 value = sysconf(name);
6634 if (value == -1 && errno != 0)
6635 posix_error();
6636 else
6637 result = PyInt_FromLong(value);
6638 }
6639 return result;
6640}
6641#endif
6642
6643
Fred Drakebec628d1999-12-15 18:31:10 +00006644/* This code is used to ensure that the tables of configuration value names
6645 * are in sorted order as required by conv_confname(), and also to build the
6646 * the exported dictionaries that are used to publish information about the
6647 * names available on the host platform.
6648 *
6649 * Sorting the table at runtime ensures that the table is properly ordered
6650 * when used, even for platforms we're not able to test on. It also makes
6651 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006652 */
Fred Drakebec628d1999-12-15 18:31:10 +00006653
6654static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006655cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006656{
6657 const struct constdef *c1 =
6658 (const struct constdef *) v1;
6659 const struct constdef *c2 =
6660 (const struct constdef *) v2;
6661
6662 return strcmp(c1->name, c2->name);
6663}
6664
6665static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006666setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006667 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006668{
Fred Drakebec628d1999-12-15 18:31:10 +00006669 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006670 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006671
6672 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6673 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006674 if (d == NULL)
6675 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006676
Barry Warsaw3155db32000-04-13 15:20:40 +00006677 for (i=0; i < tablesize; ++i) {
6678 PyObject *o = PyInt_FromLong(table[i].value);
6679 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6680 Py_XDECREF(o);
6681 Py_DECREF(d);
6682 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006683 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006684 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006685 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006686 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006687}
6688
Fred Drakebec628d1999-12-15 18:31:10 +00006689/* Return -1 on failure, 0 on success. */
6690static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006691setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006692{
6693#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006694 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006695 sizeof(posix_constants_pathconf)
6696 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006697 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006698 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006699#endif
6700#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006701 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006702 sizeof(posix_constants_confstr)
6703 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006704 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006705 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006706#endif
6707#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006708 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006709 sizeof(posix_constants_sysconf)
6710 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006711 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006712 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006713#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006714 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006715}
Fred Draked86ed291999-12-15 15:34:33 +00006716
6717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006718PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006719"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006720Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006721in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006722
6723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006724posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006725{
6726 if (!PyArg_ParseTuple(args, ":abort"))
6727 return NULL;
6728 abort();
6729 /*NOTREACHED*/
6730 Py_FatalError("abort() called from Python code didn't abort!");
6731 return NULL;
6732}
Fred Drakebec628d1999-12-15 18:31:10 +00006733
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006734#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006735PyDoc_STRVAR(win32_startfile__doc__,
6736"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006737\n\
6738This acts like double-clicking the file in Explorer, or giving the file\n\
6739name as an argument to the DOS \"start\" command: the file is opened\n\
6740with whatever application (if any) its extension is associated.\n\
6741\n\
6742startfile returns as soon as the associated application is launched.\n\
6743There is no option to wait for the application to close, and no way\n\
6744to retrieve the application's exit status.\n\
6745\n\
6746The filepath is relative to the current directory. If you want to use\n\
6747an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006748the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006749
6750static PyObject *
6751win32_startfile(PyObject *self, PyObject *args)
6752{
6753 char *filepath;
6754 HINSTANCE rc;
6755 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6756 return NULL;
6757 Py_BEGIN_ALLOW_THREADS
6758 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6759 Py_END_ALLOW_THREADS
6760 if (rc <= (HINSTANCE)32)
6761 return win32_error("startfile", filepath);
6762 Py_INCREF(Py_None);
6763 return Py_None;
6764}
6765#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006766
6767static PyMethodDef posix_methods[] = {
6768 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6769#ifdef HAVE_TTYNAME
6770 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6771#endif
6772 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6773 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006774#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006775 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006776#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006777#ifdef HAVE_LCHOWN
6778 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6779#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006780#ifdef HAVE_CHROOT
6781 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6782#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006783#ifdef HAVE_CTERMID
6784 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6785#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006786#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006787 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006788 {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006789#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006790#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006791 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006792#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006793 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6794 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6795 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006796#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006797 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006798#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006799#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006800 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006801#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006802 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6803 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6804 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006805#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006806 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006807#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006808#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006809 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006810#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006811 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006812#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006813 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006814#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006815 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6816 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6817 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006818#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006819 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006820#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006821 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006822#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006823 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6824 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006825#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006826#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006827 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6828 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006829#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006830#ifdef HAVE_FORK1
6831 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6832#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006833#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006834 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006835#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006836#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006837 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006838#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006839#ifdef HAVE_FORKPTY
6840 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6841#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006842#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006843 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006844#endif /* HAVE_GETEGID */
6845#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006846 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006847#endif /* HAVE_GETEUID */
6848#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006849 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006850#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006851#ifdef HAVE_GETGROUPS
6852 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6853#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006854 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006855#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006856 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006857#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006858#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006859 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006860#endif /* HAVE_GETPPID */
6861#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006862 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006863#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006864#ifdef HAVE_GETLOGIN
6865 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6866#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006867#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006868 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006869#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006870#ifdef HAVE_KILLPG
6871 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6872#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006873#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006874 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006875#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006876#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006877 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006878#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006879 {"popen2", win32_popen2, METH_VARARGS},
6880 {"popen3", win32_popen3, METH_VARARGS},
6881 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006882 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006883#else
6884#if defined(PYOS_OS2) && defined(PYCC_GCC)
6885 {"popen2", os2emx_popen2, METH_VARARGS},
6886 {"popen3", os2emx_popen3, METH_VARARGS},
6887 {"popen4", os2emx_popen4, METH_VARARGS},
6888#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006889#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006890#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006891#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006892 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006893#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006894#ifdef HAVE_SETEUID
6895 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6896#endif /* HAVE_SETEUID */
6897#ifdef HAVE_SETEGID
6898 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6899#endif /* HAVE_SETEGID */
6900#ifdef HAVE_SETREUID
6901 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6902#endif /* HAVE_SETREUID */
6903#ifdef HAVE_SETREGID
6904 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6905#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006906#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006907 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006908#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006909#ifdef HAVE_SETGROUPS
6910 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6911#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006912#ifdef HAVE_GETPGID
6913 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6914#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006915#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006916 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006917#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006918#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006919 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006920#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006921#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006922 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006923#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006924#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006925 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006926#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006927#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006928 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006929#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006930#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006931 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006932#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006933#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006934 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006935#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006936 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6937 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6938 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6939 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6940 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6941 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6942 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6943 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6944 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006945 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006946#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006947 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006948#endif
6949#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006950 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006951#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006952#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006953 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6954#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006955#ifdef HAVE_DEVICE_MACROS
6956 {"major", posix_major, METH_VARARGS, posix_major__doc__},
6957 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
6958 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
6959#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006960#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006961 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006962#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006963#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006964 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006965#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006966#ifdef HAVE_UNSETENV
6967 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6968#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006969#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006970 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006971#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006972#ifdef HAVE_FCHDIR
6973 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6974#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006975#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006976 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006977#endif
6978#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006979 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006980#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006981#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006982#ifdef WCOREDUMP
6983 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6984#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006985#ifdef WIFCONTINUED
6986 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6987#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006988#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006989 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006990#endif /* WIFSTOPPED */
6991#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006992 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006993#endif /* WIFSIGNALED */
6994#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006995 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006996#endif /* WIFEXITED */
6997#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006998 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006999#endif /* WEXITSTATUS */
7000#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007001 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007002#endif /* WTERMSIG */
7003#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007004 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007005#endif /* WSTOPSIG */
7006#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007007#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007008 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007009#endif
7010#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007011 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007012#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007013#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007014 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
7015#endif
7016#ifdef HAVE_TEMPNAM
7017 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7018#endif
7019#ifdef HAVE_TMPNAM
7020 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
7021#endif
Fred Drakec9680921999-12-13 16:37:25 +00007022#ifdef HAVE_CONFSTR
7023 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7024#endif
7025#ifdef HAVE_SYSCONF
7026 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7027#endif
7028#ifdef HAVE_FPATHCONF
7029 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7030#endif
7031#ifdef HAVE_PATHCONF
7032 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7033#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007034 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007035#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007036 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7037#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007038 {NULL, NULL} /* Sentinel */
7039};
7040
7041
Barry Warsaw4a342091996-12-19 23:50:02 +00007042static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007043ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007044{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007045 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007046}
7047
Guido van Rossumd48f2521997-12-05 22:19:34 +00007048#if defined(PYOS_OS2)
7049/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007050static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007051{
7052 APIRET rc;
7053 ULONG values[QSV_MAX+1];
7054 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007055 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007056
7057 Py_BEGIN_ALLOW_THREADS
7058 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7059 Py_END_ALLOW_THREADS
7060
7061 if (rc != NO_ERROR) {
7062 os2_error(rc);
7063 return -1;
7064 }
7065
Fred Drake4d1e64b2002-04-15 19:40:07 +00007066 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7067 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7068 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7069 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7070 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7071 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7072 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007073
7074 switch (values[QSV_VERSION_MINOR]) {
7075 case 0: ver = "2.00"; break;
7076 case 10: ver = "2.10"; break;
7077 case 11: ver = "2.11"; break;
7078 case 30: ver = "3.00"; break;
7079 case 40: ver = "4.00"; break;
7080 case 50: ver = "5.00"; break;
7081 default:
Tim Peters885d4572001-11-28 20:27:42 +00007082 PyOS_snprintf(tmp, sizeof(tmp),
7083 "%d-%d", values[QSV_VERSION_MAJOR],
7084 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007085 ver = &tmp[0];
7086 }
7087
7088 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007089 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007090 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007091
7092 /* Add Indicator of Which Drive was Used to Boot the System */
7093 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7094 tmp[1] = ':';
7095 tmp[2] = '\0';
7096
Fred Drake4d1e64b2002-04-15 19:40:07 +00007097 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007098}
7099#endif
7100
Barry Warsaw4a342091996-12-19 23:50:02 +00007101static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007102all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007103{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007104#ifdef F_OK
7105 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007106#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007107#ifdef R_OK
7108 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007109#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007110#ifdef W_OK
7111 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007112#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007113#ifdef X_OK
7114 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007115#endif
Fred Drakec9680921999-12-13 16:37:25 +00007116#ifdef NGROUPS_MAX
7117 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7118#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007119#ifdef TMP_MAX
7120 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7121#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007122#ifdef WCONTINUED
7123 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7124#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007125#ifdef WNOHANG
7126 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007127#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007128#ifdef WUNTRACED
7129 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7130#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007131#ifdef O_RDONLY
7132 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7133#endif
7134#ifdef O_WRONLY
7135 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7136#endif
7137#ifdef O_RDWR
7138 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7139#endif
7140#ifdef O_NDELAY
7141 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7142#endif
7143#ifdef O_NONBLOCK
7144 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7145#endif
7146#ifdef O_APPEND
7147 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7148#endif
7149#ifdef O_DSYNC
7150 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7151#endif
7152#ifdef O_RSYNC
7153 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7154#endif
7155#ifdef O_SYNC
7156 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7157#endif
7158#ifdef O_NOCTTY
7159 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7160#endif
7161#ifdef O_CREAT
7162 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7163#endif
7164#ifdef O_EXCL
7165 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7166#endif
7167#ifdef O_TRUNC
7168 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7169#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007170#ifdef O_BINARY
7171 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7172#endif
7173#ifdef O_TEXT
7174 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7175#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007176#ifdef O_LARGEFILE
7177 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7178#endif
7179
Tim Peters5aa91602002-01-30 05:46:57 +00007180/* MS Windows */
7181#ifdef O_NOINHERIT
7182 /* Don't inherit in child processes. */
7183 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7184#endif
7185#ifdef _O_SHORT_LIVED
7186 /* Optimize for short life (keep in memory). */
7187 /* MS forgot to define this one with a non-underscore form too. */
7188 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7189#endif
7190#ifdef O_TEMPORARY
7191 /* Automatically delete when last handle is closed. */
7192 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7193#endif
7194#ifdef O_RANDOM
7195 /* Optimize for random access. */
7196 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7197#endif
7198#ifdef O_SEQUENTIAL
7199 /* Optimize for sequential access. */
7200 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7201#endif
7202
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007203/* GNU extensions. */
7204#ifdef O_DIRECT
7205 /* Direct disk access. */
7206 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7207#endif
7208#ifdef O_DIRECTORY
7209 /* Must be a directory. */
7210 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7211#endif
7212#ifdef O_NOFOLLOW
7213 /* Do not follow links. */
7214 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7215#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007216
Guido van Rossum246bc171999-02-01 23:54:31 +00007217#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007218#if defined(PYOS_OS2) && defined(PYCC_GCC)
7219 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7220 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7221 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7222 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7223 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7224 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7225 if (ins(d, "P_PM", (long)P_PM)) return -1;
7226 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7227 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7228 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7229 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7230 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7231 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7232 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7233 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7234 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7235 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7236 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7237 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7238 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7239#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007240 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7241 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7242 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7243 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7244 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007245#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007246#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007247
Guido van Rossumd48f2521997-12-05 22:19:34 +00007248#if defined(PYOS_OS2)
7249 if (insertvalues(d)) return -1;
7250#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007251 return 0;
7252}
7253
7254
Tim Peters5aa91602002-01-30 05:46:57 +00007255#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007256#define INITFUNC initnt
7257#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007258
7259#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007260#define INITFUNC initos2
7261#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007262
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007263#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007264#define INITFUNC initposix
7265#define MODNAME "posix"
7266#endif
7267
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007268PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007269INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007270{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007271 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007272
Fred Drake4d1e64b2002-04-15 19:40:07 +00007273 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007274 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007275 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007276
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007277 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007278 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007279 Py_XINCREF(v);
7280 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007281 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007282 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007283
Fred Drake4d1e64b2002-04-15 19:40:07 +00007284 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007285 return;
7286
Fred Drake4d1e64b2002-04-15 19:40:07 +00007287 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007288 return;
7289
Fred Drake4d1e64b2002-04-15 19:40:07 +00007290 Py_INCREF(PyExc_OSError);
7291 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007292
Guido van Rossumb3d39562000-01-31 18:41:26 +00007293#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007294 if (posix_putenv_garbage == NULL)
7295 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007296#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007297
Guido van Rossum14648392001-12-08 18:02:58 +00007298 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007299 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007300 Py_INCREF((PyObject*) &StatResultType);
7301 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007302
Guido van Rossum14648392001-12-08 18:02:58 +00007303 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007304 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007305 Py_INCREF((PyObject*) &StatVFSResultType);
7306 PyModule_AddObject(m, "statvfs_result",
7307 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007308}